hbase

heirloom base
git clone git://git.2f30.org/hbase
Log | Files | Refs | README

commit d672d713160ed2c05d1d631d809ba17cb5a806ae
Author: Daniel Bainton <dpb@driftaway.org>
Date:   Wed, 26 Mar 2014 14:44:38 +0000

Initial commit

Diffstat:
ALICENSE/COPYING | 340+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALICENSE/COPYING.LGPL | 504+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALICENSE/LICENSE | 354+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALICENSE/LUCENT | 258+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALICENSE/OPENSOLARIS.LICENSE | 385+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ALICENSE/README | 27+++++++++++++++++++++++++++
AREADME | 5+++++
A_install/install.1b | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A_install/install.c | 436+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A_install/mkfile | 12++++++++++++
Abc/bc.1 | 222+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abc/bc.y | 743+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abc/lib.b | 241+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abc/mkfile | 11+++++++++++
Abc/yyval.sed | 22++++++++++++++++++++++
Acp/cp.1 | 218+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acp/cp.c | 1264+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acp/ln.1 | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acp/mkfile | 9+++++++++
Acp/mv.1 | 179+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adc/dc.1 | 231+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adc/dc.c | 2061+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adc/dc.h | 203+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adc/mkfile | 8++++++++
Adc/version.c | 13+++++++++++++
Add/dd.1 | 293+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Add/dd.c | 1035+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Add/mkfile | 7+++++++
Adiff/diff.1 | 493+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adiff/diff.c | 473+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adiff/diff.h | 211+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adiff/diffdir.c | 993+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adiff/diffh.c | 410+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adiff/diffreg.c | 1629+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adiff/diffver.c | 15+++++++++++++++
Adiff/mkfile | 14++++++++++++++
Aed/depsinc.mk | 1+
Aed/ed.1 | 1033+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aed/ed.c | 2822+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aed/mkfile | 8++++++++
Aexpr/expr.1 | 211+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aexpr/expr.y | 546+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aexpr/mkfile | 10++++++++++
Afind/find.1 | 558+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Afind/find.c | 1554+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Afind/mkfile | 8++++++++
Afmt/fmt.1 | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Afmt/fmt.c | 678+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Afmt/mkfile | 7+++++++
Agrep/ac.c | 578++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agrep/alloc.c | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agrep/alloc.h | 34++++++++++++++++++++++++++++++++++
Agrep/config.h | 4++++
Agrep/egrep.1 | 388+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agrep/fgrep.1 | 179+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agrep/grep.1 | 297+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agrep/grep.c | 727+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agrep/grep.h | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agrep/grid.c | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Agrep/mkfile | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Agrep/plist.c | 213+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agrep/rcomp.c | 350+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agrep/sus.c | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahd/hd.1 | 160+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahd/hd.c | 715+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahd/mkfile | 7+++++++
Alex/allprint.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/depsinc.mk | 1+
Alex/getopt.c | 222+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/header.c | 409+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/ldefs.c | 309+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/lex.1 | 131+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/libmain.c | 48++++++++++++++++++++++++++++++++++++++++++++++++
Alex/lsearch.c | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/main.c | 364+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/mkfile | 26++++++++++++++++++++++++++
Alex/nceucform | 480+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/ncform | 290+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/nrform | 188+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/once.h | 166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/parser.y | 978+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/reject.c | 158+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/search.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Alex/sgs.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/sub1.c | 1017+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/sub2.c | 1217+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/sub3.c | 395+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/wcio.c | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/yyless.c | 137+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alex/yywrap.c | 41+++++++++++++++++++++++++++++++++++++++++
Alibcommon/CHECK.c | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/_alloca.h | 27+++++++++++++++++++++++++++
Alibcommon/_malloc.h | 26++++++++++++++++++++++++++
Alibcommon/_utmpx.h | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/asciitype.c | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/asciitype.h | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/atoll.h | 8++++++++
Alibcommon/blank.h | 38++++++++++++++++++++++++++++++++++++++
Alibcommon/depsinc.mk | 2++
Alibcommon/getdir.c | 197+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/getdir.h | 33+++++++++++++++++++++++++++++++++
Alibcommon/getopt.c | 141+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/gmatch.c | 136+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/ib_alloc.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/ib_close.c | 36++++++++++++++++++++++++++++++++++++
Alibcommon/ib_free.c | 33+++++++++++++++++++++++++++++++++
Alibcommon/ib_getlin.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/ib_getw.c | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/ib_open.c | 48++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/ib_popen.c | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/ib_read.c | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/ib_seek.c | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/iblok.h | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/mbtowi.h | 22++++++++++++++++++++++
Alibcommon/memalign.c | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/memalign.h | 35+++++++++++++++++++++++++++++++++++
Alibcommon/mkfile | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/msgselect.h | 30++++++++++++++++++++++++++++++
Alibcommon/oblok.c | 260+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/oblok.h | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/pathconf.c | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/pathconf.h | 29+++++++++++++++++++++++++++++
Alibcommon/pfmt.c | 39+++++++++++++++++++++++++++++++++++++++
Alibcommon/pfmt.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/pfmt_label.c | 1+
Alibcommon/regexp.h | 1211+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/regexpr.c | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/regexpr.h | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/setlabel.c | 40++++++++++++++++++++++++++++++++++++++++
Alibcommon/setuxlabel.c | 47+++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/sfile.c | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/sfile.h | 40++++++++++++++++++++++++++++++++++++++++
Alibcommon/sighold.c | 41+++++++++++++++++++++++++++++++++++++++++
Alibcommon/sigignore.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/signal.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/sigpause.c | 48++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/sigrelse.c | 41+++++++++++++++++++++++++++++++++++++++++
Alibcommon/sigset.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/sigset.h | 38++++++++++++++++++++++++++++++++++++++
Alibcommon/strtol.c | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/sysv3.c | 2++
Alibcommon/utmpx.c | 252+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibcommon/vpfmt.c | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/COPYING.LGPL | 504+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/NOTES | 14++++++++++++++
Alibuxre/_collelem.c | 119+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/_collmult.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/bracket.c | 829+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/colldata.h | 226+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/depsinc.mk | 2++
Alibuxre/mkfile | 19+++++++++++++++++++
Alibuxre/onefile.c | 38++++++++++++++++++++++++++++++++++++++
Alibuxre/re.h | 228+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/regcomp.c | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/regdfa.c | 877+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/regdfa.h | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/regerror.c | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/regex.h | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/regexec.c | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/regfree.c | 42++++++++++++++++++++++++++++++++++++++++++
Alibuxre/regnfa.c | 1070+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/regparse.c | 1091+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/stubs.c | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alibuxre/wcharm.h | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libbio/NOTICE | 34++++++++++++++++++++++++++++++++++
Amk/libbio/README | 5+++++
Amk/libbio/bbuffered.c | 20++++++++++++++++++++
Amk/libbio/bcat.c | 46++++++++++++++++++++++++++++++++++++++++++++++
Amk/libbio/bfildes.c | 9+++++++++
Amk/libbio/bflush.c | 33+++++++++++++++++++++++++++++++++
Amk/libbio/bgetc.c | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libbio/bgetd.c | 36++++++++++++++++++++++++++++++++++++
Amk/libbio/bgetrune.c | 47+++++++++++++++++++++++++++++++++++++++++++++++
Amk/libbio/binit.c | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libbio/bio.3 | 371+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libbio/bio.h | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libbio/boffset.c | 25+++++++++++++++++++++++++
Amk/libbio/bprint.c | 14++++++++++++++
Amk/libbio/bputc.c | 20++++++++++++++++++++
Amk/libbio/bputrune.c | 23+++++++++++++++++++++++
Amk/libbio/brdline.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libbio/brdstr.c | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libbio/bread.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Amk/libbio/bseek.c | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libbio/bvprint.c | 38++++++++++++++++++++++++++++++++++++++
Amk/libbio/bwrite.c | 38++++++++++++++++++++++++++++++++++++++
Amk/libbio/depsinc.mk | 2++
Amk/libbio/lib9.h | 26++++++++++++++++++++++++++
Amk/libbio/mkfile | 23+++++++++++++++++++++++
Amk/libfmt/NOTICE | 25+++++++++++++++++++++++++
Amk/libfmt/README | 5+++++
Amk/libfmt/charstod.c | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/depsinc.mk | 2++
Amk/libfmt/dofmt.c | 617+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/dorfmt.c | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/errfmt.c | 16++++++++++++++++
Amk/libfmt/fltfmt.c | 668+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/fmt.c | 220+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/fmt.h | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/fmtdef.h | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/fmtfd.c | 36++++++++++++++++++++++++++++++++++++
Amk/libfmt/fmtfdflush.c | 22++++++++++++++++++++++
Amk/libfmt/fmtinstall.3 | 379+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/fmtlocale.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/fmtlock.c | 15+++++++++++++++
Amk/libfmt/fmtnull.c | 33+++++++++++++++++++++++++++++++++
Amk/libfmt/fmtprint.c | 36++++++++++++++++++++++++++++++++++++
Amk/libfmt/fmtquote.c | 259+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/fmtrune.c | 28++++++++++++++++++++++++++++
Amk/libfmt/fmtstr.c | 16++++++++++++++++
Amk/libfmt/fmtvprint.c | 37+++++++++++++++++++++++++++++++++++++
Amk/libfmt/fprint.c | 17+++++++++++++++++
Amk/libfmt/mkfile | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/nan.h | 4++++
Amk/libfmt/nan64.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/plan9.h | 38++++++++++++++++++++++++++++++++++++++
Amk/libfmt/pow10.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/print.3 | 482+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/print.c | 17+++++++++++++++++
Amk/libfmt/runefmtstr.c | 16++++++++++++++++
Amk/libfmt/runeseprint.c | 18++++++++++++++++++
Amk/libfmt/runesmprint.c | 18++++++++++++++++++
Amk/libfmt/runesnprint.c | 19+++++++++++++++++++
Amk/libfmt/runesprint.c | 18++++++++++++++++++
Amk/libfmt/runevseprint.c | 29+++++++++++++++++++++++++++++
Amk/libfmt/runevsmprint.c | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/runevsnprint.c | 28++++++++++++++++++++++++++++
Amk/libfmt/seprint.c | 17+++++++++++++++++
Amk/libfmt/smprint.c | 17+++++++++++++++++
Amk/libfmt/snprint.c | 18++++++++++++++++++
Amk/libfmt/sprint.c | 30++++++++++++++++++++++++++++++
Amk/libfmt/strtod.c | 520+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/test.c | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/test2.c | 9+++++++++
Amk/libfmt/test3.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/vfprint.c | 21+++++++++++++++++++++
Amk/libfmt/vseprint.c | 28++++++++++++++++++++++++++++
Amk/libfmt/vsmprint.c | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libfmt/vsnprint.c | 28++++++++++++++++++++++++++++
Amk/libregexp/NOTICE | 25+++++++++++++++++++++++++
Amk/libregexp/README | 5+++++
Amk/libregexp/depsinc.mk | 2++
Amk/libregexp/lib9.h | 10++++++++++
Amk/libregexp/mkfile | 15+++++++++++++++
Amk/libregexp/regaux.c | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libregexp/regcomp.c | 555+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libregexp/regcomp.h | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libregexp/regerror.c | 14++++++++++++++
Amk/libregexp/regexec.c | 231+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libregexp/regexp9.3 | 220+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libregexp/regexp9.7 | 141+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libregexp/regexp9.h | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libregexp/regsub.c | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libregexp/rregexec.c | 212+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libregexp/rregsub.c | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libregexp/test.c | 46++++++++++++++++++++++++++++++++++++++++++++++
Amk/libregexp/test2.c | 20++++++++++++++++++++
Amk/libutf/NOTICE | 25+++++++++++++++++++++++++
Amk/libutf/README | 5+++++
Amk/libutf/depsinc.mk | 2++
Amk/libutf/isalpharune.3 | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libutf/mkfile | 27+++++++++++++++++++++++++++
Amk/libutf/plan9.h | 29+++++++++++++++++++++++++++++
Amk/libutf/rune.3 | 194+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libutf/rune.c | 217+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libutf/runestrcat.3 | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libutf/runestrcat.c | 25+++++++++++++++++++++++++
Amk/libutf/runestrchr.c | 35+++++++++++++++++++++++++++++++++++
Amk/libutf/runestrcmp.c | 35+++++++++++++++++++++++++++++++++++
Amk/libutf/runestrcpy.c | 28++++++++++++++++++++++++++++
Amk/libutf/runestrdup.c | 30++++++++++++++++++++++++++++++
Amk/libutf/runestrecpy.c | 32++++++++++++++++++++++++++++++++
Amk/libutf/runestrlen.c | 24++++++++++++++++++++++++
Amk/libutf/runestrncat.c | 32++++++++++++++++++++++++++++++++
Amk/libutf/runestrncmp.c | 37+++++++++++++++++++++++++++++++++++++
Amk/libutf/runestrncpy.c | 33+++++++++++++++++++++++++++++++++
Amk/libutf/runestrrchr.c | 30++++++++++++++++++++++++++++++
Amk/libutf/runestrstr.c | 44++++++++++++++++++++++++++++++++++++++++++++
Amk/libutf/runetype.c | 1151+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libutf/utf.7 | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libutf/utf.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/libutf/utfdef.h | 33+++++++++++++++++++++++++++++++++
Amk/libutf/utfecpy.c | 37+++++++++++++++++++++++++++++++++++++
Amk/libutf/utflen.c | 37+++++++++++++++++++++++++++++++++++++
Amk/libutf/utfnlen.c | 41+++++++++++++++++++++++++++++++++++++++++
Amk/libutf/utfrrune.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Amk/libutf/utfrune.c | 44++++++++++++++++++++++++++++++++++++++++++++
Amk/libutf/utfutf.c | 41+++++++++++++++++++++++++++++++++++++++++
Amk/mk/NOTICE | 34++++++++++++++++++++++++++++++++++
Amk/mk/README | 5+++++
Amk/mk/arc.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/archive.c | 253+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/bufblock.c | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/env.c | 149+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/file.c | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/fns.h | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/graph.c | 279+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/job.c | 33+++++++++++++++++++++++++++++++++
Amk/mk/lex.c | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/main.c | 287+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/match.c | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/mk.1 | 693+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/mk.c | 234+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/mk.h | 185+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/mkfile | 35+++++++++++++++++++++++++++++++++++
Amk/mk/parse.c | 318+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/rc.c | 194+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/recipe.c | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/rule.c | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/run.c | 296+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/sh.c | 206+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/shell.c | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/shprint.c | 125+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/symtab.c | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/sys.h | 27+++++++++++++++++++++++++++
Amk/mk/unix.c | 341+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/var.c | 41+++++++++++++++++++++++++++++++++++++++++
Amk/mk/varsub.c | 252+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mk/word.c | 189+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amk/mkfile | 4++++
Amkfile | 5+++++
Anawk/COPYING | 340+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anawk/NOTES | 20++++++++++++++++++++
Anawk/awk.g.y | 468+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anawk/awk.h | 387+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anawk/awk.lx.l | 383+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anawk/b.c | 174+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anawk/lib.c | 852+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anawk/main.c | 215+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anawk/maketab.c | 177+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anawk/mkfile | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Anawk/nawk.1 | 585+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anawk/parse.c | 248+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anawk/run.c | 1962+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anawk/tran.c | 483+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anawk/version.c | 25+++++++++++++++++++++++++
Aod/mkfile | 8++++++++
Aod/od.1 | 291++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aod/od.c | 1078+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatch/backupfile.c | 246+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatch/backupfile.h | 39+++++++++++++++++++++++++++++++++++++++
Apatch/common.h | 119+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatch/inp.c | 485+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatch/inp.h | 32++++++++++++++++++++++++++++++++
Apatch/mkfile | 7+++++++
Apatch/mkpath.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatch/patch.1 | 700+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatch/patch.c | 1074+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatch/pathnames.h | 12++++++++++++
Apatch/pch.c | 1596+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatch/pch.h | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatch/util.c | 432+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatch/util.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Apgrep/mkfile | 11+++++++++++
Apgrep/pgrep.1 | 258+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apgrep/pgrep.c | 1748+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aprintf/mkfile | 7+++++++
Aprintf/printf.1 | 254+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aprintf/printf.c | 402+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aps/NOTES | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aps/mkfile | 8++++++++
Aps/ps.1 | 488+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aps/ps.1b | 421+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aps/ps.c | 5043+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aps/ps.dfl | 39+++++++++++++++++++++++++++++++++++++++
Ased/mkfile | 7+++++++
Ased/sed.1 | 369+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ased/sed.h | 191+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ased/sed0.c | 1266+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ased/sed1.c | 917+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ased/version.c | 22++++++++++++++++++++++
Astty/mkfile | 8++++++++
Astty/stty.1 | 293+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Astty/stty.1b | 345+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Astty/stty.c | 1490+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atar/NOTES | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atar/mkfile | 9+++++++++
Atar/tar.1 | 473+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atar/tar.c | 3204+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atar/tar.dfl | 9+++++++++
Ayacc/depsinc.mk | 1+
Ayacc/dextern | 319+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ayacc/getopt.c | 222+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ayacc/libmai.c | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Ayacc/libzer.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Ayacc/mkfile | 15+++++++++++++++
Ayacc/sgs.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Ayacc/y1.c | 1098+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ayacc/y2.c | 1758+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ayacc/y3.c | 568+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ayacc/y4.c | 485+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ayacc/y5.c | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ayacc/yacc.1 | 169+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ayacc/yaccpar | 565+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
394 files changed, 93648 insertions(+), 0 deletions(-)

diff --git a/LICENSE/COPYING b/LICENSE/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/LICENSE/COPYING.LGPL b/LICENSE/COPYING.LGPL @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/LICENSE/LICENSE b/LICENSE/LICENSE @@ -0,0 +1,354 @@ +******************************************************************************** +The license for newly written code and changes to existing code is: + + Copyright (c) 2003 Gunnar Ritter + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source distribution. + +The following tools have been rewritten from scratch: + + basename cat chown cmp copy cp + cpio* csplit cut date dd df dirname + du env expand false fold groups hd + head hostname id install kill line + listusers logins logname man mesg mkdir + mkfifo mknod mt newform news nice nl + nohup od paste pathchk pg pgrep printenv + printf priocntl ps psrinfo pwd rm + rmdir sdiff setpgrp shl sleep split stty + su sync tabs tape tapecntl tee + time touch true tty uname unexpand + users wc who whoami whodo xargs yes + + * See below for the licenses on compression codes. + +All source code and documentation has been changed intensively, thus +the above license applies to all material distributed here, further +restricted by the original licenses. + +******************************************************************************** +Caldera's License for Unix 6th Edition, Unix 7th Edition, and Unix 32V +applies to nearly all manual pages and to the utilities based on these +Unix versions: + + Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + Redistributions of source code and documentation must retain the + above copyright notice, this list of conditions and the following + disclaimer. + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + All advertising materials mentioning features or use of this software + must display the following acknowledgement: + This product includes software developed or owned by Caldera + International, Inc. + Neither the name of Caldera International, Inc. nor the names of + other contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA + INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE + LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +These utilities have been derived from Ancient Unix code: + + banner bc cal calendar chmod cksum + col comm dc deroff(1b) diff diff3 + ed egrep expr factor fgrep file find + grep join mkdir oawk pr random sed + sort sum tail tar tr tsort uniq + unit + +as well as the 'gmatch' and 'regexp' parts of libcommon. + +******************************************************************************** +Some utilities and manual pages are based on various releases of +4BSD, governed by the following license: + + Copyright (c) 1980, 1993 + The Regents of the University of California. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + This product includes software developed by the University of + California, Berkeley and its contributors. + 4. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The following utilities include 4BSD code: + + bc ching dc deroff(1b) diff diff3 fmt + ln(1b) more nawk oawk renice tcopy ul + +******************************************************************************** +The following utilities are based on Sun's OpenSolaris code; the file +OPENSOLARIS.LICENSE contains the licensing conditions for them: + + bdiff bfs dircmp echo fmtmsg getconf getopt mail + mvdir spell test what + +Some manual pages have also been derived from OpenSolaris code; see +the header of the respective page. +Changes to these programs are also subject to the original license. +******************************************************************************** +One utilities is based on the MINIX 2.0 sources, to which the +following license applies: + + Copyright (c) 1987,1997, Prentice Hall All rights reserved. + + Redistribution and use of the MINIX operating system in source and + binary forms, with or without modification, are permitted provided + that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + Neither the name of Prentice Hall nor the names of the software + authors or contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND + CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL PRENTICE HALL OR ANY AUTHORS OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The utility derived from MINIX sources is: + + ls + +******************************************************************************** +The utility 'nawk' and the library 'libuxre' are based on the Unix tools +released made available by Caldera at <http://unixtools.sourceforge.net/>. +GNU GPL 2.0 applies to 'nawk' (see the file COPYING); GNU LGPL 2.1 applies +to 'libuxre' (see COPYING.LGPL). Changes to these tools are subject to these +licenses also. + +******************************************************************************** +The 'deroff' utility is derived from Plan 9 <http://cm.bell-labs.com/plan9dist/> +and is distributed under the terms of the Lucent Public License Version 1.02; +see the file LUCENT. + +******************************************************************************** +The CRC-32 function for cpio was derived from zlib 1.1.4: + + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +******************************************************************************** +The inflate decompression code for the zip support has been derived from +Info-ZIP's zip 5.50: + + This is version 2002-Feb-16 of the Info-ZIP copyright and license. + The definitive version of this document should be available at + ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely. + + + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + For the purposes of this copyright and license, "Info-ZIP" is defined as + the following set of individuals: + + Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel + Dubois, Jean-loup Gailly, Hunter Goatley, Ian Gorman, Chris + Herborth, Dirk Haase, Greg Hartwig, Robert Heath, Jonathan Hudson, + Paul Kienitz, David Kirschbaum, Johnny Lee, Onno van der Linden, + Igor Mandrichenko, Steve P. Miller, Sergio Monesi, Keith Owens, + George Petrov, Greg Roelofs, Kai Uwe Rommel, Steve Salisbury, Dave + Smith, Christian Spieler, Antoine Verheijen, Paul von Behren, Rich + Wales, Mike White + + This software is provided "as is," without warranty of any kind, + express or implied. In no event shall Info-ZIP or its contributors + be held liable for any direct, indirect, incidental, special or + consequential damages arising out of the use of or inability to use + this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. Redistributions of source code must retain the above copyright + notice, definition, disclaimer, and this list of conditions. + + 2. Redistributions in binary form (compiled executables) must + reproduce the above copyright notice, definition, disclaimer, + and this list of conditions in documentation and/or other + materials provided with the distribution. The sole exception + to this condition is redistribution of a standard UnZipSFX + binary as part of a self-extracting archive; that is permitted + without inclusion of this license, as long as the normal + UnZipSFX banner has not been removed from the binary or + disabled. + + 3. Altered versions--including, but not limited to, ports to new + operating systems, existing ports with new graphical + interfaces, and dynamic, shared, or static library + versions--must be plainly marked as such and must not be + misrepresented as being the original source. Such altered + versions also must not be misrepresented as being Info-ZIP + releases--including, but not limited to, labeling of the + altered versions with the names "Info-ZIP" (or any variation + thereof, including, but not limited to, different + capitalizations), "Pocket UnZip," "WiZ" or "MacZip" without + the explicit permission of Info-ZIP. Such altered versions + are further prohibited from misrepresentative use of the + Zip-Bugs or Info-ZIP e-mail addresses or of the Info-ZIP + URL(s). + + 4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," + "UnZip," "UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and + "MacZip" for its own source and binary releases. + +******************************************************************************** +The unshrink decompression code is derived from Info-ZIP's unzip 5.40: + + * Copyright (c) 1994 Greg Roelofs. + * Permission is granted to any individual/institution/corporate + * entity to use, copy, redistribute or modify this software for + * any purpose whatsoever, subject to the conditions noted in the + * Frequently Asked Questions section below, plus one additional + * condition: namely, that my name not be removed from the source + * code. (Other names may, of course, be added as modifications + * are made.) Corporate legal staff (like at IBM :-) ) who have + * problems understanding this can contact me through Zip-Bugs... + + + Q. Can I use the source code of Zip and UnZip in my commercial + application? + + A. Yes, so long as you include in your product an acknowledgment; a + pointer to the original, free compression sources; and a statement + making it clear that there are no extra or hidden charges resulting + from the use of our compression code in your product (see below for + an example). The acknowledgment should appear in at least one piece + of human-readable documentation (e.g., a README file or man page), + although additionally putting it in the executable(s) is OK, too. + In other words, you are allowed to sell only your own work, not ours, + and we'd like a little credit. (Note the additional restrictions + above on the code in unreduce.c, unshrink.c, vms.c, time_lib.c, and + everything in the wince and windll subdirectories.) Contact us at + Zip-Bugs@lists.wku.edu if you have special requirements. We also + like to hear when our code is being used, but we don't require that. + + <Product> incorporates compression code from the Info-ZIP group. + There are no extra charges or costs due to the use of this code, + and the original compression sources are freely available from + http://www.cdrom.com/pub/infozip/ or ftp://ftp.cdrom.com/pub/infozip/ + on the Internet. + + If you only need compression capability, not full zipfile support, + you might want to look at zlib instead; it has fewer restrictions + on commercial use. See http://www.cdrom.com/pub/infozip/zlib/ . + +******************************************************************************** +The blast decompression code (for DCL imploded zip archive entries) was +derived from code by Mark Adler distributed with zlib 1.2.1: + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + +******************************************************************************** + +******************************************************************************** +The explode decompression code is derived from unzip 5.40; this version +of this code was put in the public domain by Mark Adler. + +******************************************************************************** + +Gunnar Ritter 2/3/07 diff --git a/LICENSE/LUCENT b/LICENSE/LUCENT @@ -0,0 +1,258 @@ +The Plan 9 software is provided under the terms of the +Lucent Public License, Version 1.02, reproduced below, +with the following exceptions: + +1. No right is granted to create derivative works of or + to redistribute (other than with the Plan 9 Operating System) + the screen imprinter fonts identified in subdirectory + /lib/font/bit/lucida and printer fonts (Lucida Sans Unicode, Lucida + Sans Italic, Lucida Sans Demibold, Lucida Typewriter, Lucida Sans + Typewriter83), identified in subdirectory /sys/lib/postscript/font. + These directories contain material copyrights by B&H Inc. and Y&Y Inc. + +2. The printer fonts identified in subdirectory /sys/lib/ghostscript/font + are subject to the GNU GPL, reproduced in the file /LICENSE.gpl. + +3. The ghostscript program in the subdirectory /sys/src/cmd/gs is + covered by the Aladdin Free Public License, reproduced in the file + /LICENSE.afpl. + +=================================================================== + +Lucent Public License Version 1.02 + +THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS PUBLIC +LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE +PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a. in the case of Lucent Technologies Inc. ("LUCENT"), the Original + Program, and + b. in the case of each Contributor, + + i. changes to the Program, and + ii. additions to the Program; + + where such changes and/or additions to the Program were added to the + Program by such Contributor itself or anyone acting on such + Contributor's behalf, and the Contributor explicitly consents, in + accordance with Section 3C, to characterization of the changes and/or + additions as Contributions. + +"Contributor" means LUCENT and any other entity that has Contributed a +Contribution to the Program. + +"Distributor" means a Recipient that distributes the Program, +modifications to the Program, or any part thereof. + +"Licensed Patents" mean patent claims licensable by a Contributor +which are necessarily infringed by the use or sale of its Contribution +alone or when combined with the Program. + +"Original Program" means the original version of the software +accompanying this Agreement as released by LUCENT, including source +code, object code and documentation, if any. + +"Program" means the Original Program and Contributions or any part +thereof + +"Recipient" means anyone who receives the Program under this +Agreement, including all Contributors. + +2. GRANT OF RIGHTS + + a. Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare derivative works of, publicly display, + publicly perform, distribute and sublicense the Contribution of such + Contributor, if any, and such derivative works, in source code and + object code form. + + b. Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, if + any, in source code and object code form. The patent license granted + by a Contributor shall also apply to the combination of the + Contribution of that Contributor and the Program if, at the time the + Contribution is added by the Contributor, such addition of the + Contribution causes such combination to be covered by the Licensed + Patents. The patent license granted by a Contributor shall not apply + to (i) any other combinations which include the Contribution, nor to + (ii) Contributions of other Contributors. No hardware per se is + licensed hereunder. + + c. Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. Each + Contributor disclaims any liability to Recipient for claims brought by + any other entity based on infringement of intellectual property rights + or otherwise. As a condition to exercising the rights and licenses + granted hereunder, each Recipient hereby assumes sole responsibility + to secure any other intellectual property rights needed, if any. For + example, if a third party patent license is required to allow + Recipient to distribute the Program, it is Recipient's responsibility + to acquire that license before distributing the Program. + + d. Each Contributor represents that to its knowledge it has sufficient + copyright rights in its Contribution, if any, to grant the copyright + license set forth in this Agreement. + +3. REQUIREMENTS + +A. Distributor may choose to distribute the Program in any form under +this Agreement or under its own license agreement, provided that: + + a. it complies with the terms and conditions of this Agreement; + + b. if the Program is distributed in source code or other tangible + form, a copy of this Agreement or Distributor's own license agreement + is included with each copy of the Program; and + + c. if distributed under Distributor's own license agreement, such + license agreement: + + i. effectively disclaims on behalf of all Contributors all warranties + and conditions, express and implied, including warranties or + conditions of title and non-infringement, and implied warranties or + conditions of merchantability and fitness for a particular purpose; + ii. effectively excludes on behalf of all Contributors all liability + for damages, including direct, indirect, special, incidental and + consequential damages, such as lost profits; and + iii. states that any provisions which differ from this Agreement are + offered by that Contributor alone and not by any other party. + +B. Each Distributor must include the following in a conspicuous + location in the Program: + + Copyright (C) 2003, Lucent Technologies Inc. and others. All Rights + Reserved. + +C. In addition, each Contributor must identify itself as the +originator of its Contribution in a manner that reasonably allows +subsequent Recipients to identify the originator of the Contribution. +Also, each Contributor must agree that the additions and/or changes +are intended to be a Contribution. Once a Contribution is contributed, +it may not thereafter be revoked. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain +responsibilities with respect to end users, business partners and the +like. While this license is intended to facilitate the commercial use +of the Program, the Distributor who includes the Program in a +commercial product offering should do so in a manner which does not +create potential liability for Contributors. Therefore, if a +Distributor includes the Program in a commercial product offering, +such Distributor ("Commercial Distributor") hereby agrees to defend +and indemnify every Contributor ("Indemnified Contributor") against +any losses, damages and costs (collectively"Losses") arising from +claims, lawsuits and other legal actions brought by a third party +against the Indemnified Contributor to the extent caused by the acts +or omissions of such Commercial Distributor in connection with its +distribution of the Program in a commercial product offering. The +obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. +In order to qualify, an Indemnified Contributor must: a) promptly +notify the Commercial Distributor in writing of such claim, and b) +allow the Commercial Distributor to control, and cooperate with the +Commercial Distributor in, the defense and any related settlement +negotiations. The Indemnified Contributor may participate in any such +claim at its own expense. + +For example, a Distributor might include the Program in a commercial +product offering, Product X. That Distributor is then a Commercial +Distributor. If that Commercial Distributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Distributor's responsibility +alone. Under this section, the Commercial Distributor would have to +defend claims against the Contributors related to those performance +claims and warranties, and if a court requires any Contributor to pay +any damages as a result, the Commercial Distributor must pay those +damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS +PROVIDED ON AN"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY +WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY +OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely +responsible for determining the appropriateness of using and +distributing the Program and assumes all risks associated with its +exercise of rights under this Agreement, including but not limited to +the risks and costs of program errors, compliance with applicable +laws, damage to or loss of data, programs or equipment, and +unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR +ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING +WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR +DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED +HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. EXPORT CONTROL + +Recipient agrees that Recipient alone is responsible for compliance +with the United States export administration regulations (and the +export control laws and regulation of any other countries). + +8. GENERAL + +If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability of +the remainder of the terms of this Agreement, and without further +action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against a Contributor with +respect to a patent applicable to software (including a cross-claim or +counterclaim in a lawsuit), then any patent licenses granted by that +Contributor to such Recipient under this Agreement shall terminate as +of the date such litigation is filed. In addition, if Recipient +institutes patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Program +itself (excluding combinations of the Program with other software or +hardware) infringes such Recipient's patent(s), then such Recipient's +rights granted under Section 2(b) shall terminate as of the date such +litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of +time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use +and distribution of the Program as soon as reasonably practicable. +However, Recipient's obligations under this Agreement and any licenses +granted by Recipient relating to the Program shall continue and +survive. + +LUCENT may publish new versions (including revisions) of this +Agreement from time to time. Each new version of the Agreement will be +given a distinguishing version number. The Program (including +Contributions) may always be distributed subject to the version of the +Agreement under which it was received. In addition, after a new +version of the Agreement is published, Contributor may elect to +distribute the Program (including its Contributions) under the new +version. No one other than LUCENT has the right to modify this +Agreement. Except as expressly stated in Sections 2(a) and 2(b) above, +Recipient receives no rights or licenses to the intellectual property +of any Contributor under this Agreement, whether expressly, by +implication, estoppel or otherwise. All rights in the Program not +expressly granted under this Agreement are reserved. + +This Agreement is governed by the laws of the State of New York and +the intellectual property laws of the United States of America. No +party to this Agreement will bring a legal action under this Agreement +more than one year after the cause of action arose. Each party waives +its rights to a jury trial in any resulting litigation. + diff --git a/LICENSE/OPENSOLARIS.LICENSE b/LICENSE/OPENSOLARIS.LICENSE @@ -0,0 +1,385 @@ +Unless otherwise noted, all files in this distribution are released +under the Common Development and Distribution License (CDDL), +Version 1.0 only. Exceptions are noted within the associated +source files. + +-------------------------------------------------------------------- + + +COMMON DEVELOPMENT AND DISTRIBUTION LICENSE Version 1.0 + +1. Definitions. + + 1.1. "Contributor" means each individual or entity that creates + or contributes to the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Software, prior Modifications used by a Contributor (if any), + and the Modifications made by that particular Contributor. + + 1.3. "Covered Software" means (a) the Original Software, or (b) + Modifications, or (c) the combination of files containing + Original Software with files containing Modifications, in + each case including portions thereof. + + 1.4. "Executable" means the Covered Software in any form other + than Source Code. + + 1.5. "Initial Developer" means the individual or entity that first + makes Original Software available under this License. + + 1.6. "Larger Work" means a work which combines Covered Software or + portions thereof with code not governed by the terms of this + License. + + 1.7. "License" means this document. + + 1.8. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed + herein. + + 1.9. "Modifications" means the Source Code and Executable form of + any of the following: + + A. Any file that results from an addition to, deletion from or + modification of the contents of a file containing Original + Software or previous Modifications; + + B. Any new file that contains any part of the Original + Software or previous Modifications; or + + C. Any new file that is contributed or otherwise made + available under the terms of this License. + + 1.10. "Original Software" means the Source Code and Executable + form of computer software code that is originally released + under this License. + + 1.11. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, + process, and apparatus claims, in any patent Licensable by + grantor. + + 1.12. "Source Code" means (a) the common form of computer software + code in which modifications are made and (b) associated + documentation included in or with such code. + + 1.13. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms + of, this License. For legal entities, "You" includes any + entity which controls, is controlled by, or is under common + control with You. For purposes of this definition, + "control" means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty + percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants. + + 2.1. The Initial Developer Grant. + + Conditioned upon Your compliance with Section 3.1 below and + subject to third party intellectual property claims, the Initial + Developer hereby grants You a world-wide, royalty-free, + non-exclusive license: + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer, to use, + reproduce, modify, display, perform, sublicense and + distribute the Original Software (or portions thereof), + with or without Modifications, and/or as part of a Larger + Work; and + + (b) under Patent Claims infringed by the making, using or + selling of Original Software, to make, have made, use, + practice, sell, and offer for sale, and/or otherwise + dispose of the Original Software (or portions thereof). + + (c) The licenses granted in Sections 2.1(a) and (b) are + effective on the date Initial Developer first distributes + or otherwise makes the Original Software available to a + third party under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: (1) for code that You delete from the Original + Software, or (2) for infringements caused by: (i) the + modification of the Original Software, or (ii) the + combination of the Original Software with other software + or devices. + + 2.2. Contributor Grant. + + Conditioned upon Your compliance with Section 3.1 below and + subject to third party intellectual property claims, each + Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor to use, reproduce, + modify, display, perform, sublicense and distribute the + Modifications created by such Contributor (or portions + thereof), either on an unmodified basis, with other + Modifications, as Covered Software and/or as part of a + Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either + alone and/or in combination with its Contributor Version + (or portions of such combination), to make, use, sell, + offer for sale, have made, and/or otherwise dispose of: + (1) Modifications made by that Contributor (or portions + thereof); and (2) the combination of Modifications made by + that Contributor with its Contributor Version (or portions + of such combination). + + (c) The licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first distributes or + otherwise makes the Modifications available to a third + party. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: (1) for any code that Contributor has deleted + from the Contributor Version; (2) for infringements caused + by: (i) third party modifications of Contributor Version, + or (ii) the combination of Modifications made by that + Contributor with other software (except as part of the + Contributor Version) or other devices; or (3) under Patent + Claims infringed by Covered Software in the absence of + Modifications made by that Contributor. + +3. Distribution Obligations. + + 3.1. Availability of Source Code. + + Any Covered Software that You distribute or otherwise make + available in Executable form must also be made available in Source + Code form and that Source Code form must be distributed only under + the terms of this License. You must include a copy of this + License with every copy of the Source Code form of the Covered + Software You distribute or otherwise make available. You must + inform recipients of any such Covered Software in Executable form + as to how they can obtain such Covered Software in Source Code + form in a reasonable manner on or through a medium customarily + used for software exchange. + + 3.2. Modifications. + + The Modifications that You create or to which You contribute are + governed by the terms of this License. You represent that You + believe Your Modifications are Your original creation(s) and/or + You have sufficient rights to grant the rights conveyed by this + License. + + 3.3. Required Notices. + + You must include a notice in each of Your Modifications that + identifies You as the Contributor of the Modification. You may + not remove or alter any copyright, patent or trademark notices + contained within the Covered Software, or any notices of licensing + or any descriptive text giving attribution to any Contributor or + the Initial Developer. + + 3.4. Application of Additional Terms. + + You may not offer or impose any terms on any Covered Software in + Source Code form that alters or restricts the applicable version + of this License or the recipients' rights hereunder. You may + choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of + Covered Software. However, you may do so only on Your own behalf, + and not on behalf of the Initial Developer or any Contributor. + You must make it absolutely clear that any such warranty, support, + indemnity or liability obligation is offered by You alone, and You + hereby agree to indemnify the Initial Developer and every + Contributor for any liability incurred by the Initial Developer or + such Contributor as a result of warranty, support, indemnity or + liability terms You offer. + + 3.5. Distribution of Executable Versions. + + You may distribute the Executable form of the Covered Software + under the terms of this License or under the terms of a license of + Your choice, which may contain terms different from this License, + provided that You are in compliance with the terms of this License + and that the license for the Executable form does not attempt to + limit or alter the recipient's rights in the Source Code form from + the rights set forth in this License. If You distribute the + Covered Software in Executable form under a different license, You + must make it absolutely clear that any terms which differ from + this License are offered by You alone, not by the Initial + Developer or Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred + by the Initial Developer or such Contributor as a result of any + such terms You offer. + + 3.6. Larger Works. + + You may create a Larger Work by combining Covered Software with + other code not governed by the terms of this License and + distribute the Larger Work as a single product. In such a case, + You must make sure the requirements of this License are fulfilled + for the Covered Software. + +4. Versions of the License. + + 4.1. New Versions. + + Sun Microsystems, Inc. is the initial license steward and may + publish revised and/or new versions of this License from time to + time. Each version will be given a distinguishing version number. + Except as provided in Section 4.3, no one other than the license + steward has the right to modify this License. + + 4.2. Effect of New Versions. + + You may always continue to use, distribute or otherwise make the + Covered Software available under the terms of the version of the + License under which You originally received the Covered Software. + If the Initial Developer includes a notice in the Original + Software prohibiting it from being distributed or otherwise made + available under any subsequent version of the License, You must + distribute and make the Covered Software available under the terms + of the version of the License under which You originally received + the Covered Software. Otherwise, You may also choose to use, + distribute or otherwise make the Covered Software available under + the terms of any subsequent version of the License published by + the license steward. + + 4.3. Modified Versions. + + When You are an Initial Developer and You want to create a new + license for Your Original Software, You may create and use a + modified version of this License if You: (a) rename the license + and remove any references to the name of the license steward + (except to note that the license differs from this License); and + (b) otherwise make it clear that the license contains terms which + differ from this License. + +5. DISCLAIMER OF WARRANTY. + + COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" + BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, + INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED + SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR + PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND + PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY + COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE + INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY + NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF + WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS + DISCLAIMER. + +6. TERMINATION. + + 6.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to + cure such breach within 30 days of becoming aware of the breach. + Provisions which, by their nature, must remain in effect beyond + the termination of this License shall survive. + + 6.2. If You assert a patent infringement claim (excluding + declaratory judgment actions) against Initial Developer or a + Contributor (the Initial Developer or Contributor against whom You + assert such claim is referred to as "Participant") alleging that + the Participant Software (meaning the Contributor Version where + the Participant is a Contributor or the Original Software where + the Participant is the Initial Developer) directly or indirectly + infringes any patent, then any and all rights granted directly or + indirectly to You by such Participant, the Initial Developer (if + the Initial Developer is not the Participant) and all Contributors + under Sections 2.1 and/or 2.2 of this License shall, upon 60 days + notice from Participant terminate prospectively and automatically + at the expiration of such 60 day notice period, unless if within + such 60 day period You withdraw Your claim with respect to the + Participant Software against such Participant either unilaterally + or pursuant to a written agreement with Participant. + + 6.3. In the event of termination under Sections 6.1 or 6.2 above, + all end user licenses that have been validly granted by You or any + distributor hereunder prior to termination (excluding licenses + granted to You by any distributor) shall survive termination. + +7. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE + INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF + COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE + LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR + CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT + LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK + STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL + INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT + APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO + NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR + CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT + APPLY TO YOU. + +8. U.S. GOVERNMENT END USERS. + + The Covered Software is a "commercial item," as that term is + defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial + computer software" (as that term is defined at 48 + C.F.R. 252.227-7014(a)(1)) and "commercial computer software + documentation" as such terms are used in 48 C.F.R. 12.212 + (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 + C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all + U.S. Government End Users acquire Covered Software with only those + rights set forth herein. This U.S. Government Rights clause is in + lieu of, and supersedes, any other FAR, DFAR, or other clause or + provision that addresses Government rights in computer software + under this License. + +9. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed + by the law of the jurisdiction specified in a notice contained + within the Original Software (except to the extent applicable law, + if any, provides otherwise), excluding such jurisdiction's + conflict-of-law provisions. Any litigation relating to this + License shall be subject to the jurisdiction of the courts located + in the jurisdiction and venue specified in a notice contained + within the Original Software, with the losing party responsible + for costs, including, without limitation, court costs and + reasonable attorneys' fees and expenses. The application of the + United Nations Convention on Contracts for the International Sale + of Goods is expressly excluded. Any law or regulation which + provides that the language of a contract shall be construed + against the drafter shall not apply to this License. You agree + that You alone are responsible for compliance with the United + States export administration regulations (and the export control + laws and regulation of any other countries) when You use, + distribute or otherwise make available any Covered Software. + +10. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or + indirectly, out of its utilization of rights under this License + and You agree to work with Initial Developer and Contributors to + distribute such responsibility on an equitable basis. Nothing + herein is intended or shall be deemed to constitute any admission + of liability. + +-------------------------------------------------------------------- + +NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND +DISTRIBUTION LICENSE (CDDL) + +For Covered Software in this distribution, this License shall +be governed by the laws of the State of California (excluding +conflict-of-law provisions). + +Any litigation relating to this License shall be subject to the +jurisdiction of the Federal Courts of the Northern District of +California and the state courts of the State of California, with +venue lying in Santa Clara County, California. diff --git a/LICENSE/README b/LICENSE/README @@ -0,0 +1,27 @@ +README for license conditions of the Heirloom Toolchest +======================================================= + +The Heirloom Toolchest is derived from a variety of sources; the +respective licensing terms can be found in the other files in this +directory; in addition, each source file contains the license terms +of the original author at its top. + +All newly written code is put under a zlib-style license (except for +additions to the GPL and LGPL code in awk and libuxre). The rationale +is that for something distributed as widely as Unix code, any license +that requires more than naming the author would only cause annoyance. + +In effect, this means that commercial Unix vendors who already have a +Unix source code license can use nearly all of this code without being +forced to mention it in other places than the source code files. + +However, if you work for such a vendor, don't do so. Instead, convince +the management to release at least the utility source. There is really +nothing to keep secret about it to have an advantage over competitors, +as any person or company can simply use the source of this or another +toolchest to have comparable functionality. So by releasing the source +to your version, you lose nothing, but you will make your users happy +since they can use it as a reference. And happy users also mean more +money in the end. + +Gunnar Ritter 9/22/03 diff --git a/README b/README @@ -0,0 +1,5 @@ +hbase is a collection of programs that complements sbase and ubase. It's meant +to be a temporary project that will shrink and die once sbase and ubase gets +implementations of most of the programs included. hbase mostly contains +programs taken from the Heirloom project, but also has other programs, such as +patch taken from FreeBSD/OpenBSD and mk taken from plan9port. diff --git a/_install/install.1b b/_install/install.1b @@ -0,0 +1,113 @@ +.\" +.\" Copyright (c) 2003 Gunnar Ritter +.\" +.\" This software is provided 'as-is', without any express or implied +.\" warranty. In no event will the authors be held liable for any damages +.\" arising from the use of this software. +.\" +.\" Permission is granted to anyone to use this software for any purpose, +.\" including commercial applications, and to alter it and redistribute +.\" it freely, subject to the following restrictions: +.\" +.\" 1. The origin of this software must not be misrepresented; you must not +.\" claim that you wrote the original software. If you use this software +.\" in a product, an acknowledgment in the product documentation would be +.\" appreciated but is not required. +.\" +.\" 2. Altered source versions must be plainly marked as such, and must not be +.\" misrepresented as being the original software. +.\" +.\" 3. This notice may not be removed or altered from any source distribution. +.\" Sccsid @(#)install.1b 1.3 (gritter) 4/17/03 +.TH INSTALL 1B "4/17/03" "Heirloom Toolchest" "BSD System Compatibility" +.SH NAME +install \- (BSD) install files +.SH SYNOPSIS +.HP +.ad l +.nh +\fB/usr/ucb/install\fR [\fB\-cs\fR] [\fB-g\fI\ group\fR] [\fB\-m\fI\ mode\fR] +[\fB-o\fI\ owner\fR] +\fIfile1 file2\fR +.HP +.ad l +.nh +\fB/usr/ucb/install\fR [\fB\-cs\fR] [\fB-g\fI\ group\fR] [\fB\-m\fI\ mode\fR] +[\fB-o\fI\ owner\fR] +\fIfile\fR\ .\ .\ .\ \fIdirectory\fR +.HP +.ad l +.nh +\fB/usr/ucb/install\fR \fB\-d\fR [\fB\-g\fI\ group\fR] [\fB\-m\fI\ mode\fR] +[\fB\-o\fI\ owner\fR] \fIdirectory\fR +.br +.ad b +.hy 1 +.SH DESCRIPTION +The +.I install +command copies one regular file to a destination file +or one or more regular files into a destination directory. +It is commonly used within Makefiles +to install newly created software components. +.PP +If the +.B \-d +option is present, +.I install +creates the named +.IR directory , +also creating non-existent parent directories. +It is not an error if the directory already exists. +The +.BR \-g , +.BR \-m , +and +.B \-o +options +apply to the last pathname component only; +attributes are set whether the directory is newly created or not. +Parent directories are always created using a default mode of 777 +minus umask +and default ownerships. +.PP +The following options are also accepted: +.TP 10 +.B \-c +This option is ignored and exists for compatibility only. +Ancient versions of this command removed the source file +unless this option was present. +.TP 10 +.B \-s +Strip the target files +(i.\|e. execute the +.IR strip (1) +command on them). +.TP 10 +\fB\-g\fI group\fR +Use the given +.I group +ownership for target files. +By default, +the group of the invoking user is used. +.TP 10 +\fB\-m\fI mode\fR +Set the access permissions of target files to octal +.IR mode . +By default, +mode 755 is used. +.TP 10 +\fB\-o\fI owner\fR +Specifies the +.I owner +of target files. +By default, +target files are owned by the invoking user. +.SH "SEE ALSO" +cp(1), +chgrp(1), +chmod(1), +chown(1), +make(1), +mkdir(1), +strip(1) diff --git a/_install/install.c b/_install/install.c @@ -0,0 +1,436 @@ +/* + * install - (BSD style) install files + * + * Gunnar Ritter, Freiburg i. Br., Germany, March 2003. + */ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 +#define USED __attribute__ ((used)) +#elif defined __GNUC__ +#define USED __attribute__ ((unused)) +#else +#define USED +#endif +static const char sccsid[] USED = "@(#)/usr/ucb/install.sl 1.12 (gritter) 5/29/05"; + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <libgen.h> +#include <limits.h> +#include <pwd.h> +#include <grp.h> + +enum okay { + OKAY = 0, + STOP = 1 +}; + +static int mflag; /* -m option present */ +static int sflag; /* strip files */ +static mode_t mode = 0755; /* mode to set */ +static int dflag; /* create directories */ +static int gflag; /* set group */ +static gid_t group; /* group to set */ +static int oflag; /* set owner */ +static uid_t owner; /* owner to set */ +static int errcnt; /* count of errors */ +static char *progname; /* argv[0] to main */ + +void * +srealloc(void *op, size_t size) +{ + void *np; + + if ((np = realloc(op, size)) == NULL) { + write(2, "no memory\n", 10); + _exit(077); + } + return np; +} + +void * +smalloc(size_t size) +{ + return srealloc(NULL, size); +} + +uid_t +getowner(const char *string) +{ + struct passwd *pwd; + char *x; + long val; + + if ((pwd = getpwnam(string)) != NULL) + return pwd->pw_uid; + val = strtoul(string, &x, 10); + if (*x != '\0' || *string == '+' || *string == '-') { + fprintf(stderr, "%s: unknown user %s.\n", progname, string); + exit(1); + } + return val; +} + +gid_t +getgroup(const char *string) +{ + struct group *grp; + char *x; + long val; + + if ((grp = getgrnam(string)) != NULL) + return grp->gr_gid; + val = strtoul(string, &x, 10); + if (*x != '\0' || *string == '+' || *string == '-') { + fprintf(stderr, "%s: unknown group %s.\n", progname, string); + exit(1); + } + return val; +} + +void +getpath(const char *path, char **file, char **filend, size_t *sz, size_t *slen) +{ + *sz = 14 + strlen(path) + 2; + *file = smalloc(*sz); + *filend = *file; + if (path[0] == '/' && path[1] == '\0') + *(*filend)++ = '/'; + else { + const char *cp = path; + while ((*(*filend)++ = *cp++) != '\0'); + (*filend)[-1] = '/'; + } + *slen = *filend - *file; +} + +void +setpath(const char *base, char **file, char **filend, + size_t slen, size_t *sz, size_t *ss) +{ + if (slen + (*ss = strlen(base)) >= *sz) { + *sz += slen + *ss + 15; + *file = srealloc(*file, *sz); + *filend = &(*file)[slen]; + } + strcpy(*filend, base); +} + +void +fdcopy(const char *src, const struct stat *ssp, const int sfd, + const char *tgt, const struct stat *dsp, const int dfd) +{ + char *buf; + size_t bufsize; + ssize_t rsz, wo, wt; + + if ((bufsize = ssp->st_blksize) < dsp->st_blksize) + if ((bufsize = dsp->st_blksize) <= 0) + bufsize = 512; + buf = smalloc(bufsize); + while ((rsz = read(sfd, buf, bufsize)) > 0) { + wt = 0; + do { + if ((wo = write(dfd, buf + wt, rsz - wt)) < 0) { + fprintf(stderr, "%s: write: %s: %s\n", + progname, tgt, + strerror(errno)); + errcnt |= 01; + unlink(tgt); + free(buf); + return; + } + wt += wo; + } while (wt < rsz); + } + if (rsz < 0) { + fprintf(stderr, "%s: read: %s: %s\n", + progname, src, strerror(errno)); + errcnt |= 01; + unlink(tgt); + } + free(buf); +} + +static void +usage(void) +{ + fprintf(stderr, "\ +usage: %s [-cs] [-g group] [-m mode] [-o owner] file ... destination\n\ + %s -d [-g group] [-m mode] [-o owner] dir\n", + progname, progname); + exit(2); +} + +static void +strip(const char *file) +{ + const char cpr[] = "strip "; + char *cmd, *cp; + const char *sp; + + cp = cmd = smalloc(strlen(cpr) + strlen(file) + 1); + for (sp = cpr; *sp; sp++) + *cp++ = *sp; + for (sp = file; *sp; sp++) + *cp++ = *sp; + *cp = '\0'; + system(cmd); + free(cmd); +} + +static enum okay +chgown(const char *fn, struct stat *sp) +{ + struct stat st; + + if (sp == NULL) { + if (stat(fn, &st) < 0) { + fprintf(stderr, "%s: stat: %s: %s\n", + progname, fn, strerror(errno)); + errcnt |= 1; + return STOP; + } + sp = &st; + } + if (!oflag) + owner = sp->st_uid; + if (!gflag) + group = sp->st_gid; + if (chown(fn, owner, group) < 0) { + fprintf(stderr, "%s: chown: %s: %s\n", progname, fn, + strerror(errno)); + errcnt |= 01; + return STOP; + } + return OKAY; +} + +static enum okay +check(const char *src, const char *tgt, const struct stat *dsp, + struct stat *ssp) +{ + if (stat(src, ssp) < 0) { + fprintf(stderr, "%s: %s: %s\n", progname, src, + strerror(errno)); + errcnt |= 01; + return STOP; + } + if ((ssp->st_mode&S_IFMT) != S_IFREG && strcmp(src, "/dev/null")) { + fprintf(stderr, "%s: %s isn't a regular file.\n", + progname, src); + errcnt |= 01; + return STOP; + } + if (dsp && (ssp->st_dev == dsp->st_dev && ssp->st_ino == dsp->st_ino)) { + fprintf(stderr, "%s: %s and %s are the same file.\n", + progname, src, tgt); + errcnt |= 01; + return STOP; + } + return OKAY; +} + +static void +cp(const char *src, const char *tgt, struct stat *dsp) +{ + struct stat sst, nst; + int sfd, dfd; + + if (check(src, tgt, dsp, &sst) != OKAY) + return; + unlink(tgt); + if ((dfd = creat(tgt, 0700)) < 0 || fchmod(dfd, 0700) < 0 || + fstat(dfd, &nst) < 0) { + fprintf(stderr, "%s: %s: %s\n", progname, src, + strerror(errno)); + errcnt |= 01; + if (dfd >= 0) + close(dfd); + return; + } + if ((sfd = open(src, O_RDONLY)) < 0) { + fprintf(stderr, "%s: open: %s: %s\n", progname, src, + strerror(errno)); + errcnt |= 01; + return; + } + fdcopy(src, &sst, sfd, tgt, &nst, dfd); + close(dfd); + close(sfd); + if (sflag) + strip(tgt); + if (oflag || gflag) + chgown(tgt, &nst); + if (chmod(tgt, mode) < 0) { + fprintf(stderr, "%s: %s: %s\n", progname, tgt, strerror(errno)); + errcnt |= 01; + } +} + +static void +installf(int ac, char **av) +{ + struct stat dst, ust; + + if (lstat(av[ac-1], &dst) == 0) { + if ((dst.st_mode&S_IFMT) != S_IFLNK || + stat(av[ac-1], &ust) < 0) + ust = dst; + if ((ust.st_mode&S_IFMT) == S_IFDIR) { + char *copy, *cend; + size_t sz, slen, ss; + int i; + + getpath(av[ac-1], &copy, &cend, &sz, &slen); + for (i = 0; i < ac-1; i++) { + setpath(basename(av[i]), &copy, &cend, + slen, &sz, &ss); + cp(av[i], copy, stat(copy, &dst) < 0 ? + NULL : &dst); + } + } else if (ac > 2) + usage(); + else + cp(av[0], av[1], &ust); + } else if (ac > 2) + usage(); + else + cp(av[0], av[1], NULL); +} + +static enum okay +makedir(const char *dir) +{ + struct stat st; + + if (mkdir(dir, 0777) < 0) { + if (errno == EEXIST) { + if (stat(dir, &st) < 0 || + (st.st_mode&S_IFMT) != S_IFDIR){ + fprintf(stderr, "%s: %s is not a directory\n", + progname, dir); + errcnt |= 01; + return STOP; + } + } else { + fprintf(stderr, "%s: mkdir: %s: %s\n", + progname, dir, strerror(errno)); + errcnt |= 01; + return STOP; + } + } + return OKAY; +} +static void +installd(char *dir) +{ + struct stat st; + int sgid_bit; + char *slash; + char c; + + slash = dir; + do { + while (*slash == '/') + slash++; + while (*slash != '/' && *slash != '\0') + slash++; + c = *slash; + *slash = '\0'; + if (makedir(dir) != OKAY) + return; + if (c == '\0') { + if (oflag || gflag) + if (chgown(dir, NULL) != OKAY) + return; + if (mflag) { + sgid_bit = stat(dir, &st) == 0 && + st.st_mode&S_ISGID ? S_ISGID : 0; + if (chmod(dir, mode | sgid_bit) < 0) { + fprintf(stderr, "%s: chmod: %s: %s\n", + progname, dir, + strerror(errno)); + errcnt |= 01; + return; + } + } + } + *slash = c; + } while (c != '\0'); +} + +int +main(int argc, char **argv) +{ + const char optstring[] = "csg:m:o:d"; + int i; + + progname = basename(argv[0]); + while ((i = getopt(argc, argv, optstring)) != EOF) { + switch (i) { + case 'c': + /* no-op */ + break; + case 's': + sflag = 1; + break; + case 'g': + gflag = 1; + group = getgroup(optarg); + break; + case 'm': + mflag = 1; + mode = strtol(optarg, NULL, 8); + break; + case 'o': + oflag = 1; + owner = getowner(optarg); + break; + case 'd': + dflag = 1; + break; + default: + usage(); + } + } + if (dflag) { + if (argc == optind || argc > optind + 1) + usage(); + if (mflag) + mode &= ~(mode_t)S_ISGID; + installd(argv[optind]); + } else { + if (argc < optind + 2) + usage(); + installf(argc - optind, &argv[optind]); + } + return errcnt; +} diff --git a/_install/mkfile b/_install/mkfile @@ -0,0 +1,12 @@ +BIN = _install +TARG = __install +OBJ = install.o +INSTALL_BIN = install +INSTALL_MAN1b = install.1b +CLEAN_FILES = install + +<$mkbuild/mk.default + +__install:QV: $BIN + mv _install install + diff --git a/bc/bc.1 b/bc/bc.1 @@ -0,0 +1,222 @@ +.\" +.\" Sccsid @(#)bc.1 1.7 (gritter) 10/11/03 +.\" Derived from bc(1), Unix 7th edition: +.\" Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" Redistributions of source code and documentation must retain the +.\" above copyright notice, this list of conditions and the following +.\" disclaimer. +.\" Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed or owned by Caldera +.\" International, Inc. +.\" Neither the name of Caldera International, Inc. nor the names of +.\" other contributors may be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA +.\" INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE +.\" LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.TH BC 1 "10/11/03" "Heirloom Toolchest" "User Commands" +.SH NAME +bc \- arbitrary-precision arithmetic language +.SH SYNOPSIS +\fBbc\fR [\fB\-c\fR] [\fB\-l\fR] [\fIfile\fR ... ] +.SH DESCRIPTION +.I Bc +is an interactive processor for a language which resembles +C but provides unlimited precision arithmetic. +It takes input from any files given, then reads +the standard input. +The +.B \-l +argument stands for the name +of an arbitrary precision math library. +The syntax for +.I bc +programs is as follows; +L means letter a-z, +E means expression, S means statement. +.HP 6 +Comments +.br +are enclosed in /* and */. +.HP 6 +Names +.br +simple variables: L +.br +array elements: L [ E ] +.br +The words `ibase', `obase', and `scale' +.HP 6 +Other operands +.br +arbitrarily long numbers with optional sign and decimal point. +.br +( E ) +.br +sqrt ( E ) +.br +length ( E ) number of significant decimal digits +.br +scale ( E ) number of digits right of decimal point +.br +L ( E , ... , E ) +.HP 6 +Operators +.br ++ \- * / % ^ +(% is remainder; ^ is power) +.br +++ \-\- (prefix and postfix; apply to names) +.br +== <= >= != < > +.br += =+ =\- =* =/ =% =^ +.br +.HP 6 +Statements +.br +E +.br +{ S ; ... ; S } +.br +if ( E ) S +.br +while ( E ) S +.br +for ( E ; E ; E ) S +.br +null statement +.br +break +.br +quit +.HP 6 +Function definitions +.br +define L ( L ,..., L ) { +.br + auto L, ... , L +.br + S; ... S +.br + return ( E ) +.br +} +.HP 6 +Functions in +.B \-l +math library +.br +s(x) sine +.br +c(x) cosine +.br +e(x) exponential +.br +l(x) log +.br +a(x) arctangent +.br +j(n,x) Bessel function +.PP +.DT +All function arguments are passed by value. +.PP +The value of a statement that is an expression is printed +unless the main operator is an assignment. +Either semicolons or newlines may separate statements. +Assignment to +.I scale +influences the number of digits to be retained on arithmetic +operations in the manner of +.IR dc (1). +Assignments to +.I ibase +or +.I obase +set the input and output number radix respectively. +.PP +The same letter may be used as an array, a function, +and a simple variable simultaneously. +All variables are global to the program. +`Auto' variables are pushed down during function calls. +When using arrays as function arguments +or defining them as automatic variables +empty square brackets must follow the array name. +.PP +For example +.PP +.nf +scale = 20 +define e(x){ + auto a, b, c, i, s + a = 1 + b = 1 + s = 1 + for(i=1; 1==1; i++){ + a = a*x + b = b*i + c = a/b + if(c == 0) return(s) + s = s+c + } +} +.PP +.fi +defines a function to compute an approximate value of +the exponential function and +.PP +.nf + for(i=1; i<=10; i++) e(i) +.fi +.PP +prints approximate values of the exponential function of +the first ten integers. +.PP +.I Bc +is actually a preprocessor for +.IR dc (1), +which it invokes automatically, unless the +.B \-c +(compile only) +option is present. +In this case the +.I dc +input is sent to the standard output instead. +.SH FILES +.ta \w'/usr/5lib/lib.b 'u +/usr/5lib/lib.b mathematical library +.br +dc(1) desk calculator proper +.SH "SEE ALSO" +dc(1) +.br +L. L. Cherry and R. Morris, +.I +BC \- An arbitrary precision desk-calculator language +.SH BUGS +No &&, \(or\|\(or, or ! operators. +.br +.I For +statement must have all three E's. +.br +.I Quit +is interpreted when read, not when executed. diff --git a/bc/bc.y b/bc/bc.y @@ -0,0 +1,743 @@ +%{ +/* from 4.4BSD /usr/src/usr.bin/bc/bc.y */ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This module is believed to contain source code proprietary to AT&T. + * Use and redistribution is subject to the Berkeley Software License + * Agreement and your Software Agreement with AT&T (Western Electric). + * + * from bc.y 8.1 (Berkeley) 6/6/93 + */ +/* + * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * Redistributions of source code and documentation must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed or owned by Caldera + * International, Inc. + * Neither the name of Caldera International, Inc. nor the names of + * other contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA + * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE + * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 +#define USED __attribute__ ((used)) +#elif defined __GNUC__ +#define USED __attribute__ ((unused)) +#else +#define USED +#endif +static const char sccsid[] USED = "@(#)bc.sl 1.24 (gritter) 7/3/05"; +#include <unistd.h> +#include <signal.h> +#include <limits.h> +#include <inttypes.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +typedef intptr_t YYSTYPE; +#define YYSTYPE YYSTYPE + static int cpeek(int c, int yes, int no); + static int getch(void); + static intptr_t bundle(int a, ...); + static void routput(intptr_t *p); + static void output(intptr_t *p); + static void conout(intptr_t p, intptr_t s); + static void pp(intptr_t); + static void tp(intptr_t); + static void yyinit(int argc, char *argv[]); + static intptr_t *getout(void); + static intptr_t *getf(intptr_t); + static intptr_t *geta(intptr_t); + static void yyerror(const char *); + static void cantopen(const char *); + extern int yylex(void); + +#if defined (__GLIBC__) && defined (_IO_getc_unlocked) +#undef getc +#define getc(f) _IO_getc_unlocked(f) +#endif +%} +%right '=' +%left '+' '-' +%left '*' '/' '%' +%right '^' +%left UMINUS + +%term LETTER DIGIT SQRT LENGTH _IF FFF EQ +%term _WHILE _FOR NE LE GE INCR DECR +%term _RETURN _BREAK _DEFINE BASE OBASE SCALE +%term EQPL EQMI EQMUL EQDIV EQREM EQEXP +%term _AUTO DOT +%term QSTR + +%{ +#define THIS_BC_STRING_MAX 1000 +static FILE *in; +static char cary[LINE_MAX + 1], *cp = { cary }; +static char string[THIS_BC_STRING_MAX + 3], *str = {string}; +static int crs = '0'; +static int rcrs = '0'; /* reset crs */ +static int bindx = 0; +static int lev = 0; +static int ln; +static char *ss; +static int bstack[10] = { 0 }; +static char *numb[15] = { + " 0", " 1", " 2", " 3", " 4", " 5", + " 6", " 7", " 8", " 9", " 10", " 11", + " 12", " 13", " 14" }; +static intptr_t *pre, *post; +%} +%% +start : + | start stat tail + { output( (intptr_t *)$2 );} + | start def dargs ')' '{' dlist slist '}' + { bundle( 6,pre, $7, post ,"0",numb[lev],"Q"); + conout( $$, $2 ); + rcrs = crs; + output( (intptr_t *)"" ); + lev = bindx = 0; + } + ; + +dlist : tail + | dlist _AUTO dlets tail + ; + +stat : e + { bundle(2, $1, "ps." ); } + | + { bundle(1, "" ); } + | QSTR + { bundle(3,"[",$1,"]P");} + | LETTER '=' e + { bundle(3, $3, "s", $1 ); } + | LETTER '[' e ']' '=' e + { bundle(4, $6, $3, ":", geta($1)); } + | LETTER EQOP e + { bundle(6, "l", $1, $3, $2, "s", $1 ); } + | LETTER '[' e ']' EQOP e + { bundle(8,$3, ";", geta($1), $6, $5, $3, ":", geta($1));} + | _BREAK + { bundle(2, numb[lev-bstack[bindx-1]], "Q" ); } + | _RETURN '(' e ')' + { bundle(4, $3, post, numb[lev], "Q" ); } + | _RETURN '(' ')' + { bundle(4, "0", post, numb[lev], "Q" ); } + | _RETURN + { bundle(4,"0",post,numb[lev],"Q"); } + | SCALE '=' e + { bundle(2, $3, "k"); } + | SCALE EQOP e + { bundle(4,"K",$3,$2,"k"); } + | BASE '=' e + { bundle(2,$3, "i"); } + | BASE EQOP e + { bundle(4,"I",$3,$2,"i"); } + | OBASE '=' e + { bundle(2,$3,"o"); } + | OBASE EQOP e + { bundle(4,"O",$3,$2,"o"); } + | '{' slist '}' + { $$ = $2; } + | FFF + { bundle(1,"fY"); } + | error + { bundle(1,"c"); } + | _IF CRS BLEV '(' re ')' stat + { conout( $7, $2 ); + bundle(3, $5, $2, " " ); + } + | _WHILE CRS '(' re ')' stat BLEV + { bundle(3, $6, $4, $2 ); + conout( $$, $2 ); + bundle(3, $4, $2, " " ); + } + | fprefix CRS re ';' e ')' stat BLEV + { bundle(5, $7, $5, "s.", $3, $2 ); + conout( $$, $2 ); + bundle(5, $1, "s.", $3, $2, " " ); + } + | '~' LETTER '=' e + { bundle(3,$4,"S",$2); } + ; + +EQOP : EQPL + { $$ = (intptr_t)"+"; } + | EQMI + { $$ = (intptr_t)"-"; } + | EQMUL + { $$ = (intptr_t)"*"; } + | EQDIV + { $$ = (intptr_t)"/"; } + | EQREM + { $$ = (intptr_t)"%%"; } + | EQEXP + { $$ = (intptr_t)"^"; } + ; + +fprefix : _FOR '(' e ';' + { $$ = $3; } + ; + +BLEV : + { --bindx; } + ; + +slist : stat + | slist tail stat + { bundle(2, $1, $3 ); } + ; + +tail : '\n' + {ln++;} + | ';' + ; + +re : e EQ e + { bundle(3, $1, $3, "=" ); } + | e '<' e + { bundle(3, $1, $3, ">" ); } + | e '>' e + { bundle(3, $1, $3, "<" ); } + | e NE e + { bundle(3, $1, $3, "!=" ); } + | e GE e + { bundle(3, $1, $3, "!>" ); } + | e LE e + { bundle(3, $1, $3, "!<" ); } + | e + { bundle(2, $1, " 0!=" ); } + ; + +e : e '+' e + { bundle(3, $1, $3, "+" ); } + | e '-' e + { bundle(3, $1, $3, "-" ); } + | '-' e %prec UMINUS + { bundle(3, " 0", $2, "-" ); } + | e '*' e + { bundle(3, $1, $3, "*" ); } + | e '/' e + { bundle(3, $1, $3, "/" ); } + | e '%' e + { bundle(3, $1, $3, "%%" ); } + | e '^' e + { bundle(3, $1, $3, "^" ); } + | LETTER '[' e ']' + { bundle(3,$3, ";", geta($1)); } + | LETTER INCR + { bundle(4, "l", $1, "d1+s", $1 ); } + | INCR LETTER + { bundle(4, "l", $2, "1+ds", $2 ); } + | DECR LETTER + { bundle(4, "l", $2, "1-ds", $2 ); } + | LETTER DECR + { bundle(4, "l", $1, "d1-s", $1 ); } + | LETTER '[' e ']' INCR + { bundle(7,$3,";",geta($1),"d1+",$3,":",geta($1)); } + | INCR LETTER '[' e ']' + { bundle(7,$4,";",geta($2),"1+d",$4,":",geta($2)); } + | LETTER '[' e ']' DECR + { bundle(7,$3,";",geta($1),"d1-",$3,":",geta($1)); } + | DECR LETTER '[' e ']' + { bundle(7,$4,";",geta($2),"1-d",$4,":",geta($2)); } + | SCALE INCR + { bundle(1,"Kd1+k"); } + | INCR SCALE + { bundle(1,"K1+dk"); } + | SCALE DECR + { bundle(1,"Kd1-k"); } + | DECR SCALE + { bundle(1,"K1-dk"); } + | BASE INCR + { bundle(1,"Id1+i"); } + | INCR BASE + { bundle(1,"I1+di"); } + | BASE DECR + { bundle(1,"Id1-i"); } + | DECR BASE + { bundle(1,"I1-di"); } + | OBASE INCR + { bundle(1,"Od1+o"); } + | INCR OBASE + { bundle(1,"O1+do"); } + | OBASE DECR + { bundle(1,"Od1-o"); } + | DECR OBASE + { bundle(1,"O1-do"); } + | LETTER '(' cargs ')' + { bundle(4, $3, "l", getf($1), "x" ); } + | LETTER '(' ')' + { bundle(3, "l", getf($1), "x" ); } + | cons + { bundle(2, " ", $1 ); } + | DOT cons + { bundle(2, " .", $2 ); } + | cons DOT cons + { bundle(4, " ", $1, ".", $3 ); } + | cons DOT + { bundle(3, " ", $1, "." ); } + | DOT + { $$ = (intptr_t)"l."; } + | LETTER + { bundle(2, "l", $1 ); } + | LETTER '=' e + { bundle(3, $3, "ds", $1 ); } + | LETTER EQOP e %prec '=' + { bundle(6, "l", $1, $3, $2, "ds", $1 ); } + | LETTER '[' e ']' '=' e + { bundle(5,$6,"d",$3,":",geta($1)); } + | LETTER '[' e ']' EQOP e + { bundle(9,$3,";",geta($1),$6,$5,"d",$3,":",geta($1)); } + | LENGTH '(' e ')' + { bundle(2,$3,"Z"); } + | SCALE '(' e ')' + { bundle(2,$3,"X"); } /* must be before '(' e ')' */ + | '(' e ')' + { $$ = $2; } + | '?' + { bundle(1, "?" ); } + | SQRT '(' e ')' + { bundle(2, $3, "v" ); } + | '~' LETTER + { bundle(2,"L",$2); } + | SCALE '=' e + { bundle(2,$3,"dk"); } + | SCALE EQOP e %prec '=' + { bundle(4,"K",$3,$2,"dk"); } + | BASE '=' e + { bundle(2,$3,"di"); } + | BASE EQOP e %prec '=' + { bundle(4,"I",$3,$2,"di"); } + | OBASE '=' e + { bundle(2,$3,"do"); } + | OBASE EQOP e %prec '=' + { bundle(4,"O",$3,$2,"do"); } + | SCALE + { bundle(1,"K"); } + | BASE + { bundle(1,"I"); } + | OBASE + { bundle(1,"O"); } + ; + +cargs : eora + | cargs ',' eora + { bundle(2, $1, $3 ); } + ; +eora: e + | LETTER '[' ']' + {bundle(2,"l",geta($1)); } + ; + +cons : constant + { *cp++ = '\0'; } + +constant: + '_' + { $$ = (intptr_t)cp; *cp++ = '_'; } + | DIGIT + { $$ = (intptr_t)cp; *cp++ = $1; } + | constant DIGIT + { *cp++ = $2; } + ; + +CRS : + { $$ = (intptr_t)cp; *cp++ = crs++; *cp++ = '\0'; + if(crs == '[')crs+=3; + if(crs == 'a')crs='{'; + if(crs >= 0241){yyerror("program too big"); + getout(); + } + bstack[bindx++] = lev++; } + ; + +def : _DEFINE LETTER '(' + { $$ = (intptr_t)getf($2); + pre = (intptr_t *)""; + post = (intptr_t *)""; + lev = 1; + bstack[bindx=0] = 0; + } + ; + +dargs : + | lora + { pp( $1 ); } + | dargs ',' lora + { pp( $3 ); } + ; + +dlets : lora + { tp($1); } + | dlets ',' lora + { tp($3); } + ; +lora : LETTER + | LETTER '[' ']' + { $$ = (intptr_t)geta($1); } + ; + +%% +# define error 256 + +static int peekc = -1; +static int sargc; +static int ifile; +static char **sargv; + +static char funtab[52] = { + 01,0,02,0,03,0,04,0,05,0,06,0,07,0,010,0,011,0,012,0,013,0,014,0,015,0,016,0,017,0, + 020,0,021,0,022,0,023,0,024,0,025,0,026,0,027,0,030,0,031,0,032,0 }; +static char atab[52] = { + 0241,0,0242,0,0243,0,0244,0,0245,0,0246,0,0247,0,0250,0,0251,0,0252,0,0253,0, + 0254,0,0255,0,0256,0,0257,0,0260,0,0261,0,0262,0,0263,0,0264,0,0265,0,0266,0, + 0267,0,0270,0,0271,0,0272,0}; +static char *letr[26] = { + "a","b","c","d","e","f","g","h","i","j", + "k","l","m","n","o","p","q","r","s","t", + "u","v","w","x","y","z" } ; +/*static char *dot = { "." };*/ + +int +yylex(void){ + int c, ch; +restart: + c = getch(); + peekc = -1; + while( c == ' ' || c == '\t' ) c = getch(); + if(c == '\\'){ + getch(); + goto restart; + } + if( c<= 'z' && c >= 'a' ) { + /* look ahead to look for reserved words */ + peekc = getch(); + if( peekc >= 'a' && peekc <= 'z' ){ /* must be reserved word */ + if( c=='i' && peekc=='f' ){ c=_IF; goto skip; } + if( c=='w' && peekc=='h' ){ c=_WHILE; goto skip; } + if( c=='f' && peekc=='o' ){ c=_FOR; goto skip; } + if( c=='s' && peekc=='q' ){ c=SQRT; goto skip; } + if( c=='r' && peekc=='e' ){ c=_RETURN; goto skip; } + if( c=='b' && peekc=='r' ){ c=_BREAK; goto skip; } + if( c=='d' && peekc=='e' ){ c=_DEFINE; goto skip; } + if( c=='s' && peekc=='c' ){ c= SCALE; goto skip; } + if( c=='b' && peekc=='a' ){ c=BASE; goto skip; } + if( c=='i' && peekc == 'b'){ c=BASE; goto skip; } + if( c=='o' && peekc=='b' ){ c=OBASE; goto skip; } + if( c=='d' && peekc=='i' ){ c=FFF; goto skip; } + if( c=='a' && peekc=='u' ){ c=_AUTO; goto skip; } + if( c == 'l' && peekc=='e'){ c=LENGTH; goto skip; } + if( c == 'q' && peekc == 'u'){getout();} + /* could not be found */ + return( error ); + skip: /* skip over rest of word */ + peekc = -1; + while( (ch = getch()) >= 'a' && ch <= 'z' ); + peekc = ch; + return( c ); + } + + /* usual case; just one single letter */ + + yylval = (intptr_t)letr[c-'a']; + return( LETTER ); + } + if( c>= '0' && c <= '9' || c>= 'A' && c<= 'F' ){ + yylval = c; + return( DIGIT ); + } + switch( c ){ + case '.': return( DOT ); + case '=': + switch( peekc = getch() ){ + case '=': c=EQ; goto gotit; + case '+': c=EQPL; goto gotit; + case '-': c=EQMI; goto gotit; + case '*': c=EQMUL; goto gotit; + case '/': c=EQDIV; goto gotit; + case '%': c=EQREM; goto gotit; + case '^': c=EQEXP; goto gotit; + default: return( '=' ); + gotit: peekc = -1; return(c); + } + case '+': return( cpeek( '+', INCR, cpeek( '=', EQPL, '+') ) ); + case '-': return( cpeek( '-', DECR, cpeek( '=', EQMI, '-') ) ) ; + case '<': return( cpeek( '=', LE, '<' ) ); + case '>': return( cpeek( '=', GE, '>' ) ); + case '!': return( cpeek( '=', NE, '!' ) ); + case '/': + if((peekc = getch()) == '*'){ + peekc = -1; + while((getch() != '*') || ((peekc = getch()) != '/')); + peekc = -1; + goto restart; + } + else if (peekc == '=') { + c=EQDIV; + goto gotit; + } + else return(c); + case '*': + return( cpeek( '=', EQMUL, '*' ) ); + case '%': + return( cpeek( '=', EQREM, '%' ) ); + case '^': + return( cpeek( '=', EQEXP, '^' ) ); + case '"': + yylval = (intptr_t)str; + while((c=getch()) != '"'){*str++ = c; + if(str >= &string[sizeof string - 1]){yyerror("string space exceeded"); + getout(); + } + } + *str++ = '\0'; + return(QSTR); + default: return( c ); + } +} + +static int +cpeek(int c, int yes, int no){ + if( (peekc=getch()) != c ) return( no ); + else { + peekc = -1; + return( yes ); + } +} + +static int +getch(void){ + int ch; +loop: + ch = (peekc < 0) ? getc(in) : peekc; + peekc = -1; + if(ch != EOF)return(ch); + if(++ifile > sargc){ + if(ifile >= sargc+2)getout(); + in = stdin; + ln = 0; + goto loop; + } + fclose(in); + if((in = fopen(sargv[ifile],"r")) != NULL){ + ln = 0; + ss = sargv[ifile]; + goto loop; + } + cantopen(sargv[ifile]); + return EOF; +} +# define b_sp_max 3000 +static intptr_t b_space [ b_sp_max ]; +static intptr_t * b_sp_nxt = { b_space }; + +static int bdebug = 0; + +static intptr_t +bundle(int a, ...){ + intptr_t i, *q; + va_list ap; + + i = a; + q = b_sp_nxt; + if( bdebug ) printf("bundle %ld elements at %lo\n",(long)i, (long)q ); + va_start(ap, a); + while(i-- > 0){ + if( b_sp_nxt >= & b_space[b_sp_max] ) yyerror( "bundling space exceeded" ); + * b_sp_nxt++ = va_arg(ap, intptr_t); + } + va_end(ap); + * b_sp_nxt++ = 0; + yyval = (intptr_t)q; + return( (intptr_t)q ); +} + +static void +routput(intptr_t *p) { + if( bdebug ) printf("routput(%lo)\n", (long)p ); + if( p >= &b_space[0] && p < &b_space[b_sp_max]){ + /* part of a bundle */ + while( *p != 0 ) routput( (intptr_t *)*p++ ); + } + else printf( (char *)p ); /* character string */ +} + +static void +output(intptr_t *p) { + routput( p ); + b_sp_nxt = & b_space[0]; + printf( "\n" ); + fflush(stdout); + cp = cary; + crs = rcrs; +} + +static void +conout(intptr_t p, intptr_t s) { + printf("["); + routput( (intptr_t *)p ); + printf("]s%s\n", (char *)s ); + fflush(stdout); + lev--; +} + +static void +yyerror(const char *s) { + if(ifile > sargc)ss="teletype"; + fprintf(stderr, "%s on line %d, %s\n", + s ,ss?ln+1:0,ss?ss:"command line"); + cp = cary; + crs = rcrs; + bindx = 0; + lev = 0; + b_sp_nxt = &b_space[0]; +} + +static void +cantopen(const char *fn) +{ + char spc[280]; + char *oss = ss; + + ss = 0; + snprintf(spc, sizeof spc, "can't open input file %s", fn); + yyerror(spc); + ss = oss; +} + +static void +pp(intptr_t s) { + /* puts the relevant stuff on pre and post for the letter s */ + + bundle(3, "S", s, pre ); + pre = (intptr_t *)yyval; + bundle(4, post, "L", s, "s." ); + post = (intptr_t *)yyval; +} + +static void +tp(intptr_t s) { /* same as pp, but for temps */ + bundle(3, "0S", s, pre ); + pre = (intptr_t *)yyval; + bundle(4, post, "L", s, "s." ); + post = (intptr_t *)yyval; +} + +static void +yyinit(int argc,char **argv) { + signal(SIGINT, SIG_IGN); + sargv=argv; + sargc= -- argc; + if(sargc == 0)in=stdin; + else if((in = fopen(sargv[1],"r")) == NULL) { + cantopen(sargv[1]); + exit(0); + } + ifile = 1; + ln = 0; + ss = sargv[1]; +} + +static intptr_t * +getout(void){ + printf("q"); + fflush(stdout); + exit(0); + /*NOTREACHED*/ + return(NULL); +} + +static intptr_t * +getf(intptr_t p) { + return(intptr_t *)(&funtab[2*(*((char *)p) -0141)]); +} + +static intptr_t * +geta(intptr_t p) { + return(intptr_t *)(&atab[2*(*((char *)p) - 0141)]); +} + +int +main(int argc, char **argv) +{ + extern int yyparse(void); + const char optstring[] = "cdl"; + int p[2]; + int i; + int cflag = 0, lflag = 0; + + +#ifdef __GLIBC__ + putenv("POSIXLY_CORRECT=1"); +#endif + while ((i = getopt(argc, argv, optstring)) != EOF) { + switch (i) { + case 'd': + case 'c': + cflag = 1; + break; + case 'l': + lflag = 1; + break; + default: + exit(2); + } + } + argv += optind - 1, argc -= optind - 1; + if (cflag) { + yyinit(argc, argv); + yyparse(); + exit(0); + } + if (lflag) { + *argv-- = LIBB; + argc++; + } + pipe(p); + if (fork()==0) { + close(1); + dup(p[1]); + close(p[0]); + close(p[1]); + yyinit(argc, argv); + yyparse(); + exit(0); + } + close(0); + dup(p[0]); + close(p[0]); + close(p[1]); + execl(DC, "dc", "-", NULL); + execl("/usr/5bin/dc", "dc", "-", NULL); + execl("/usr/local/bin/dc", "dc", "-", NULL); + execl("/usr/contrib/bin/dc", "dc", "-", NULL); + execl("/usr/bin/dc", "dc", "-", NULL); + return(1); +} diff --git a/bc/lib.b b/bc/lib.b @@ -0,0 +1,241 @@ +/* from 4.4BSD /usr/src/usr.bin/bc/bc.library */ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This module is believed to contain source code proprietary to AT&T. + * Use and redistribution is subject to the Berkeley Software License + * Agreement and your Software Agreement with AT&T (Western Electric). + * + * from bc.library 8.1 (Berkeley) 6/6/93 + */ +/* + * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * Redistributions of source code and documentation must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed or owned by Caldera + * International, Inc. + * Neither the name of Caldera International, Inc. nor the names of + * other contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA + * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE + * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Sccsid @(#)lib.b 1.4 (gritter) 8/26/02 */ + +scale = 20 +define e(x){ + auto a, b, c, d, e, g, t, w, y + + t = scale + scale = t + .434*x + 1 + + w = 0 + if(x<0){ + x = -x + w = 1 + } + y = 0 + while(x>2){ + x = x/2 + y = y + 1 + } + + a=1 + b=1 + c=b + d=1 + e=1 + for(a=1;1==1;a++){ + b=b*x + c=c*a+b + d=d*a + g = c/d + if(g == e){ + g = g/1 + while(y--){ + g = g*g + } + scale = t + if(w==1) return(1/g) + return(g/1) + } + e=g + } +} + +define l(x){ + auto a, b, c, d, e, f, g, u, s, t + if(x <=0) return(1-10^scale) + t = scale + + f=1 + scale = scale + scale(x) - length(x) + 1 + s=scale + while(x > 2){ + s = s + (length(x)-scale(x))/2 + 1 + if(s>0) scale = s + x = sqrt(x) + f=f*2 + } + while(x < .5){ + s = s + (length(x)-scale(x))/2 + 1 + if(s>0) scale = s + x = sqrt(x) + f=f*2 + } + + scale = t + length(f) - scale(f) + 1 + u = (x-1)/(x+1) + + scale = scale + 1.1*length(t) - 1.1*scale(t) + s = u*u + b = 2*f + c = b + d = 1 + e = 1 + for(a=3;1==1;a=a+2){ + b=b*s + c=c*a+d*b + d=d*a + g=c/d + if(g==e){ + scale = t + return(u*c/d) + } + e=g + } +} + +define s(x){ + auto a, b, c, s, t, y, p, n, i + t = scale + y = x/.7853 + s = t + length(y) - scale(y) + if(s<t) s=t + scale = s + p = a(1) + + scale = 0 + if(x>=0) n = (x/(2*p)+1)/2 + if(x<0) n = (x/(2*p)-1)/2 + x = x - 4*n*p + if(n%2!=0) x = -x + + scale = t + length(1.2*t) - scale(1.2*t) + y = -x*x + a = x + b = 1 + s = x + for(i=3; 1==1; i=i+2){ + a = a*y + b = b*i*(i-1) + c = a/b + if(c==0){scale=t; return(s/1)} + s = s+c + } +} + +define c(x){ + auto t + t = scale + scale = scale+1 + x = s(x+2*a(1)) + scale = t + return(x/1) +} + +define a(x){ + auto a, b, c, d, e, f, g, s, t + if(x==0) return(0) + if(x==1) { + if(scale<52) { +return(.7853981633974483096156608458198757210492923498437764/1) + } + } + t = scale + f=1 + while(x > .5){ + scale = scale + 1 + x= -(1-sqrt(1.+x*x))/x + f=f*2 + } + while(x < -.5){ + scale = scale + 1 + x = -(1-sqrt(1.+x*x))/x + f=f*2 + } + s = -x*x + b = f + c = f + d = 1 + e = 1 + for(a=3;1==1;a=a+2){ + b=b*s + c=c*a+d*b + d=d*a + g=c/d + if(g==e){ + scale = t + return(x*c/d) + } + e=g + } +} + +define j(n,x){ +auto a,b,c,d,e,g,i,s,k,t + + t = scale + k = 1.36*x + 1.16*t - n + k = length(k) - scale(k) + if(k>0) scale = scale + k + +s= -x*x/4 +if(n<0){ + n= -n + x= -x + } +a=1 +c=1 +for(i=1;i<=n;i++){ + a=a*x + c = c*2*i + } +b=a +d=1 +e=1 +for(i=1;1;i++){ + a=a*s + b=b*i*(n+i) + a + c=c*i*(n+i) + g=b/c + if(g==e){ + scale = t + return(g/1) + } + e=g + } +} diff --git a/bc/mkfile b/bc/mkfile @@ -0,0 +1,11 @@ +BIN = bc +OBJ = bc.o +LOCAL_CFLAGS = -DDC=\"$BINDIR/dc\" -DLIBB=\"$LIBDIR/lib.b\" +CLEAN_FILES = bc.c +INSTALL_BIN = bc +INSTALL_LIB = lib.b +INSTALL_MAN1 = bc.1 +DEPS = yacc + +<$mkbuild/mk.default + diff --git a/bc/yyval.sed b/bc/yyval.sed @@ -0,0 +1,22 @@ +# +# Sccsid @(#)yyval.sed 1.3 (gritter) 4/27/04 +# +# bison has a yacc-compatible yyval, but it is a local variable inside +# yyparse(). Making the variable global is necessary to make bc work +# with a bison-generated parser. +1,2 { + /Bison/ { + :look + /YYSTYPE/ { + a\ + YYSTYPE yyval; + :repl + s/^[ ]*YYSTYPE[ ]*yyval;// + n + t + b repl + } + n + b look + } +} diff --git a/cp/cp.1 b/cp/cp.1 @@ -0,0 +1,218 @@ +.\" +.\" Sccsid @(#)cp.1 1.26 (gritter) 5/3/05 +.\" Parts taken from cp(1), Unix 7th edition: +.\" Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" Redistributions of source code and documentation must retain the +.\" above copyright notice, this list of conditions and the following +.\" disclaimer. +.\" Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed or owned by Caldera +.\" International, Inc. +.\" Neither the name of Caldera International, Inc. nor the names of +.\" other contributors may be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA +.\" INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE +.\" LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.TH CP 1 "5/3/05" "Heirloom Toolchest" "User Commands" +.SH NAME +cp \- copy files +.SH SYNOPSIS +\fBcp\fR +[\fB\-adDfiHLpPrRs\fR] [\fB\-b\ \fIsize\fR] +\fIfile1\fR [\fIfile2\fR .\ .\ .\ ] \fItarget\fR +.SH DESCRIPTION +.I File1 +is copied onto +.IR target . +If +.I target +is an existing regular file, +its content is overwritten. +Its mode and owner are preserved; +the mode of the source file is used otherwise. +.PP +If +.I target +is a directory, +one or more files are copied +into the directory with their original file-names. +.PP +.I Cp +refuses to copy a file onto itself. +.PP +The +.I cp +command accepts the following options: +.TP +.B \-i +.I Cp +will ask for confirmation +before overwriting an existing target file. +For +.B /usr/5bin/cp +and +.BR /usr/5bin/s42/cp , +.I cp +will also ask for confirmation before overwriting a directory +with the +.I \-r +or +.I \-R +option. +For +.BR /usr/5bin/cp , +this flag will be automatically disabled +if standard input is not a terminal. +.TP +.B \-p +.I Cp +will try to preserve access and modification times, +user and group ownerships, +and file permission bits. +Failing to preserve these modes +is always considered an error, +but only +.BR /usr/5bin/s42/cp , +.BR /usr/5bin/posix2001/cp , +and +.B /usr/5bin/posix/cp +will print an error message. +.TP +.B \-r +The source file operands may be directories +that will be copied recursively. +Symbolic links are followed. +The content of all non-directory files encountered +is tried to be reproduced in a regular file. +.PP +The following options have been added by POSIX.2: +.TP +.B \-f +If overwriting a target file fails, +.I cp +will try to unlink that file and proceed. +.TP +.B \-R +The source file operands may be directories +that will be copied recursively. +Special files +such as block and character devices, +FIFOs, +and symbolic links encountered during traversal +are recreated in the target hierarchy. +If a symbolic link is given as an operand, +its target is copied. +.PP +The following options have been added by POSIX.1-2001: +.TP +.B \-H +With the +.I \-R +option, follow symbolic links given as operands, +but do not follow symbolic links encountered during traversal +of the source hierarchy. +This is the default. +.TP +.B \-L +With the +.I \-R +option, follow all symbolic links. +.TP +.B \-P +With the +.I \-R +option, do not follow any symbolic links. +.PP +The following options are extensions: +.TP +.B \-a +Perform a recursive copy and, if possible, +preserve hard links as well as any attributes. +This is the same as the combination of the +.I \-Rdp +options. +.TP +\fB\-b\ \fIsize\fR +With this option given, +.I cp +performs input and output in units of +.I size +bytes. +The default size depends on the current input file. +.TP +.B \-d +With the +.I \-r +or +.I \-R +options, +hard links between copied files are usually splitted, +i.\|e. each copied file is assigned to a separate i-node. +When this option is given, +hard links between copied files +are reproduced in the destination hierarchy. +.TP +.B \-D +Causes +.I cp +to use direct i/o +when copying file data. +See the description of `O_DIRECT' in +.IR open (2) +for more information. +.TP +.B \-s +With this option, +.I cp +prints i/o statistics for each single file +of which data was copied. +.SH "SEE ALSO" +cat(1), +cpio(1), +mv(1), +pr(1), +rm(1) +.SH NOTES +Use either +.RS +.sp +.B cp +.B \-\- +.I \-file +.I target +.sp +.RE +or +.RS +.sp +.B cp +.I ./\-file +.I target +.sp +.RE +to copy files that begin with a hyphen character. +.PP +A copy of a symbolic link +contains the same pathname as the original. +Symbolic links with relative pathnames +may thus change or lose their target +if copied to a different level in the file hierarchy. diff --git a/cp/cp.c b/cp/cp.c @@ -0,0 +1,1264 @@ +/* + * cp - copy files + * + * Gunnar Ritter, Freiburg i. Br., Germany, July 2002. + */ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 +#define USED __attribute__ ((used)) +#elif defined __GNUC__ +#define USED __attribute__ ((unused)) +#else +#define USED +#endif +#if defined (SUS) +static const char sccsid[] USED = "@(#)cp_sus.sl 1.84 (gritter) 3/4/06"; +#elif defined (S42) +static const char sccsid[] USED = "@(#)cp_s42.sl 1.84 (gritter) 3/4/06"; +#else +static const char sccsid[] USED = "@(#)cp.sl 1.84 (gritter) 3/4/06"; +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <malloc.h> +#include <errno.h> +#include <libgen.h> +#include <limits.h> +#include <dirent.h> +#include <utime.h> +#include "sfile.h" +#include "memalign.h" +#include "alloca.h" + +#ifndef S_IFDOOR +#define S_IFDOOR 0xD000 /* Solaris door */ +#endif +#ifndef S_IFNAM +#define S_IFNAM 0x5000 /* XENIX special named file */ +#endif +#ifndef S_IFNWK +#define S_IFNWK 0x9000 /* HP-UX network special file */ +#endif + +static enum { + PERS_CP, + PERS_MV, + PERS_LN +} pers; + +enum okay { + OKAY = 0, + STOP = 1 +}; + +struct islot { + struct islot *i_lln; + struct islot *i_rln; + char *i_name; + ino_t i_ino; +}; + +struct dslot { + struct dslot *d_nxt; + struct islot *d_isl; + dev_t d_dev; +}; + +static struct dslot *d0; + +static unsigned errcnt; /* count of errors */ +static long bflag; /* buffer size */ +static int dflag; /* preserve hard links */ +#ifdef O_DIRECT +static int Dflag; /* use direct i/o */ +#endif /* O_DIRECT */ +static int fflag; /* force */ +static int iflag; /* ask before overwriting */ +static int nflag; /* ln: do not remove links */ +static int pflag; /* preserve owner and times */ +static int rflag; /* recursive, read FIFOs */ +static int Rflag; /* recursive, recreate FIFOs */ +static int sflag; /* make symlinks / show statistics */ +static int HLPflag; /* -H, -L, or -P */ +static int ontty; /* stdin is a terminal */ +static mode_t umsk; /* current umask */ +static uid_t myuid; /* current uid */ +static gid_t mygid; /* current gid */ +static char *progname; /* argv[0] to main() */ +static struct islot *inull; /* inode tree null element */ +static void (*go)(const char *, const char *, struct stat *, int, + int (*statfn)(const char *, struct stat *)); + +static mode_t +check_suid(const struct stat *sp, mode_t mode) +{ + if (sp->st_uid != myuid || sp->st_gid != mygid) { + mode &= ~(mode_t)S_ISUID; + if ((sp->st_mode&S_IFMT) != S_IFDIR || sp->st_mode&0010) + mode &= ~(mode_t)S_ISGID; + if ((sp->st_mode&S_IFMT) == S_IFDIR || sp->st_gid != mygid) + mode &= ~(mode_t)S_ISGID; + } + return mode; +} + +static void +nomem(void) +{ + write(2, progname, strlen(progname)); + write(2, ": Insufficient memory space.\n", 29); + _exit(077); +} + +static void * +srealloc(void *vp, size_t nbytes) +{ + void *p; + + if ((p = realloc(vp, nbytes)) == NULL) + nomem(); + return p; +} + +static void * +smalloc(size_t nbytes) +{ + return srealloc(NULL, nbytes); +} + +static void * +scalloc(size_t nelem, size_t nbytes) +{ + void *p; + + if ((p = calloc(nelem, nbytes)) == NULL) + nomem(); + return p; +} + +static void +usage(void) +{ + switch (pers) { + case PERS_CP: + fprintf(stderr, "\ +Usage: %s [-i] [-p] f1 f2\n\ + %s [-i] [-p] f1 ... fn d1\n\ + %s [-i] [-p] [-r] d1 d2\n", + progname, progname, progname); + break; + case PERS_MV: + fprintf(stderr, "\ +Usage: %s [-f] [-i] f1 f2\n\ + %s [-f] [-i] f1 ... fn d1\n\ + %s [-f] [-i] d1 d2\n", + progname, progname, progname); + break; + case PERS_LN: + { +#if defined (SUS) + const char nstr[] = ""; +#else /* !SUS */ + const char nstr[] = "[-n] "; +#endif /* !SUS */ + fprintf(stderr, "\ +Usage: %s [-f] %s[-s] f1 f2\n\ + %s [-f] %s[-s] f1 ... fn d1\n\ + %s [-f] %s[-s] d1 d2\n", + progname, nstr, progname, nstr, + progname, nstr); + } + break; + } + exit(2); +} + +static void +freeislots(struct islot *ip) +{ + if (ip == inull) + return; + freeislots(ip->i_lln); + freeislots(ip->i_rln); + free(ip->i_name); + free(ip); +} + +static void +freedslots(void) +{ + struct dslot *dp, *dn; + + for (dp = d0; dp; dp = dn) { + dn = dp->d_nxt; + freeislots(dp->d_isl); + free(dp); + } + d0 = NULL; +} + +static struct islot * +isplay(ino_t ino, struct islot *x) +{ + struct islot hdr; + struct islot *leftmax, *rightmin; + struct islot *y; + + hdr.i_lln = hdr.i_rln = inull; + leftmax = rightmin = &hdr; + inull->i_ino = ino; + while (ino != x->i_ino) { + if (ino < x->i_ino) { + if (ino < x->i_lln->i_ino) { + y = x->i_lln; + x->i_lln = y->i_rln; + y->i_rln = x; + x = y; + } + if (x->i_lln == inull) + break; + rightmin->i_lln = x; + rightmin = x; + x = x->i_lln; + } else { + if (ino > x->i_rln->i_ino) { + y = x->i_rln; + x->i_rln = y->i_lln; + y->i_lln = x; + x = y; + } + if (x->i_rln == inull) + break; + leftmax->i_rln = x; + leftmax = x; + x = x->i_rln; + } + } + leftmax->i_rln = x->i_lln; + rightmin->i_lln = x->i_rln; + x->i_lln = hdr.i_rln; + x->i_rln = hdr.i_lln; + inull->i_ino = !ino; + return x; +} + +static struct islot * +ifind(ino_t ino, struct islot **it) +{ + if (*it == NULL) + return NULL; + *it = isplay(ino, *it); + return (*it)->i_ino == ino ? *it : NULL; +} + +static void +iput(struct islot *ik, struct islot **it) +{ + if ((*it) == NULL) { + ik->i_lln = ik->i_rln = inull; + (*it) = ik; + } else { + /*(*it) = isplay(ik->i_ino, (*it));*/ + /* ifind() is always called before */ + if (ik->i_ino < (*it)->i_ino) { + ik->i_lln = (*it)->i_lln; + ik->i_rln = (*it); + (*it)->i_lln = inull; + (*it) = ik; + } else if ((*it)->i_ino < ik->i_ino) { + ik->i_rln = (*it)->i_rln; + ik->i_lln = (*it); + (*it)->i_rln = inull; + (*it) = ik; + } + } +} +static int +canlink(const char *path, const struct stat *sp) +{ + struct dslot *ds, *dp; + struct islot *ip; + + for (ds = d0, dp = NULL; ds; dp = ds, ds = ds->d_nxt) + if (ds->d_dev == sp->st_dev) + break; + if (ds == NULL) { + ds = scalloc(1, sizeof *ds); + ds->d_dev = sp->st_dev; + if (d0 == NULL) + d0 = ds; + else + dp->d_nxt = ds; + } + if ((ip = ifind(sp->st_ino, &ds->d_isl)) == NULL) { + ip = scalloc(1, sizeof *ip); + ip->i_name = smalloc(strlen(path) + 1); + strcpy(ip->i_name, path); + ip->i_ino = sp->st_ino; + iput(ip, &ds->d_isl); + } else { + if (link(ip->i_name, path) == 0) + return 1; + } + return 0; +} + +static enum okay +confirm(void) +{ + enum okay yes = STOP; + char c; + + if (read(0, &c, 1) == 1) { + yes = (c == 'y' || c == 'Y') ? OKAY : STOP; + while (c != '\n' && read(0, &c, 1) == 1); + } + return yes; +} + +static void +permissions(const char *path, const struct stat *ssp) +{ + mode_t mode; + + mode = ssp->st_mode & 07777; + if (pflag) { + struct utimbuf ut; + ut.actime = ssp->st_atime; + ut.modtime = ssp->st_mtime; + if (utime(path, &ut) < 0) { +#if defined (SUS) || defined (S42) + fprintf(stderr, "%s: cannot set times for %s\n%s: %s\n", + progname, path, + progname, strerror(errno)); +#endif /* SUS || S42 */ + if (pers != PERS_MV) + errcnt |= 010; + } + if (myuid == 0) { + if (chown(path, ssp->st_uid, ssp->st_gid) < 0) { +#if defined (SUS) || defined (S42) + fprintf(stderr, + "%s: cannot change owner and group of %s\n%s: %s\n", + progname, path, + progname, strerror(errno)); +#endif /* SUS || S42 */ + if (pers != PERS_MV) + errcnt |= 010; + mode &= ~(mode_t)(S_ISUID|S_ISGID); + } + } else + mode = check_suid(ssp, mode); + } else + mode = check_suid(ssp, mode & ~umsk); + if (chmod(path, mode) < 0) { +#if defined (SUS) || defined (S42) + fprintf(stderr, "%s: cannot set permissions for %s\n%s: %s\n", + progname, path, + progname, strerror(errno)); +#endif /* SUS || S42 */ + if (pers != PERS_MV) + errcnt |= 010; + } +} + +static size_t +balign(const struct stat *ssp, const struct stat *dsp, + long long size, size_t prefd) +{ + int n, m; + size_t s; + + n = (ssp->st_mode&S_IFMT) == S_IFREG && ssp->st_blksize >= 0 ? + ssp->st_blksize : 512; + m = (dsp->st_mode&S_IFMT) == S_IFREG && dsp->st_blksize >= 0 ? + dsp->st_blksize : 512; + if (prefd <= size && prefd % n == 0 && prefd % m == 0) + return prefd; + else if (n % m == 0) + return n; + else if (m % n == 0) + return m; + else { + s = n; + while (s % m) + s *= 2; + return s; + } +} + +/*ARGSUSED*/ +void +writerr(void *vp, int count, int written) +{ +} + +static long long +fdcopy(const char *src, const struct stat *ssp, const int sfd, + const char *tgt, const struct stat *dsp, const int dfd) +{ + static long pagesize; + static char *buf = NULL; + static size_t bufsize; + ssize_t rsz, wo, wt; + size_t blksize; + long long copied = 0; +#ifdef O_DIRECT + int sfl = 0, dfl = 0, haverest = 0, dioen = 0; + off_t remsz = 0; +#endif + +#ifdef __linux__ + if (!bflag && !Dflag && ssp->st_size > 0) { + long long sent; + + if ((sent = sfile(dfd, sfd, ssp->st_mode, ssp->st_size)) == + ssp->st_size) + return sent; + if (sent < 0) + goto err; + } +#endif /* __linux__ */ + if (pagesize == 0) + if ((pagesize = sysconf(_SC_PAGESIZE)) < 0) + pagesize = 4096; + if (bflag) + blksize = bflag; +#ifdef O_DIRECT + else if (Dflag) + blksize = balign(ssp, dsp, ssp->st_size, 1048576); +#endif /* O_DIRECT */ + else + blksize = balign(ssp, dsp, ssp->st_size, 4096); + if (blksize > bufsize) { + if (buf) + free(buf); + if ((buf = memalign(pagesize, bufsize = blksize)) == 0) + nomem(); + } +#ifdef O_DIRECT + if (Dflag) { + if ((ssp->st_mode&S_IFMT) == S_IFREG && + ssp->st_size > blksize || + (ssp->st_mode&S_IFMT) == S_IFBLK) { + sfl = fcntl(sfd, F_GETFL); + fcntl(sfd, F_SETFL, sfl | O_DIRECT); + remsz = ssp->st_size; + } + if ((dsp->st_mode&S_IFMT) == S_IFREG || + (dsp->st_mode&S_IFMT) == S_IFBLK) { + dfl = fcntl(dfd, F_GETFL); + fcntl(dfd, F_SETFL, dfl | O_DIRECT); + dioen = 1; + } + } +#endif /* O_DIRECT */ + while ((rsz = read(sfd, buf, blksize)) > 0) { +#ifdef O_DIRECT + if (Dflag && rsz < blksize && dioen != 0) { + fcntl(dfd, F_SETFL, dfl); + dioen = 0; + } +#endif /* O_DIRECT */ + wt = 0; + do { + if ((wo = write(dfd, buf + wt, rsz - wt)) < 0) { +#ifdef __linux__ + err: +#endif /* __linux__ */ + fprintf(stderr, "%s: %s: write: %s\n", + progname, tgt, + strerror(errno)); + errcnt |= 04; +#ifdef notdef + if ((dsp->st_mode&S_IFMT) == S_IFREG) + unlink(tgt); +#endif /* notdef */ + return copied; + } + wt += wo; + copied += wo; + } while (wt < rsz); +#ifdef O_DIRECT + if (Dflag && ssp->st_size > blksize && + (ssp->st_mode&S_IFMT) == S_IFREG) { + remsz -= rsz; + if (remsz > 0 && remsz < blksize && + haverest == 0 && (bflag || + remsz<(blksize=balign(ssp, dsp, + ssp->st_size, 4096)))) { + fcntl(sfd, F_SETFL, sfl); + haverest = 1; + } + } +#endif /* O_DIRECT */ + } + if (rsz < 0) { + fprintf(stderr, "%s: %s: read: %s\n", + progname, src, strerror(errno)); + errcnt |= 04; +#ifdef notdef + if ((dsp->st_mode&S_IFMT) == S_IFREG) + unlink(tgt); +#endif /* notdef */ + } +#ifdef O_DIRECT + if (haverest) { +#if !defined (__FreeBSD__) && !defined (__DragonFly__) && !defined (__APPLE__) + fdatasync(dfd); +#else /* __FreeBSD__, __DragonFly__, __APPLE__ */ + fsync(dfd); +#endif /* __FreeBSD_, __DragonFly__, __APPLE__ */ + } +#endif /* O_DIRECT */ + return copied; +} + +static void +filecopy(const char *src, const struct stat *ssp, + const char *tgt, const struct stat *dsp) +{ + struct stat stbuf; + mode_t mode; + int sfd, dfd; + float f, s, t; + struct timeval tv1, tv2; + struct rusage ru1, ru2; + long long copied = 0; + + if (sflag) { + gettimeofday(&tv1, NULL); + getrusage(RUSAGE_SELF, &ru1); + } + if ((sfd = open(src, O_RDONLY)) < 0) { + fprintf(stderr, "%s: cannot open %s\n%s: %s\n", + progname, src, + src, strerror(errno)); + errcnt |= 01; + return; + } + mode = check_suid(ssp, ssp->st_mode & 07777); + if ((dfd = creat(tgt, mode)) < 0) + if (pers != PERS_MV && dsp != NULL && fflag && unlink(tgt) == 0) + dfd = creat(tgt, mode); + if (dfd < 0) { + fprintf(stderr, "%s: cannot create %s\n%s: %s\n", + progname, tgt, + progname, strerror(errno)); + errcnt |= 01; + goto end1; + } + if (fstat(dfd, &stbuf) < 0) { + fprintf(stderr, "%s: fstat for %s failed: %s\n", + progname, tgt, strerror(errno)); + errcnt |= 04; + goto end2; + } + copied = fdcopy(src, ssp, sfd, tgt, &stbuf, dfd); +end2: + if (pflag) + permissions(tgt, ssp); + if (close(dfd) < 0) { + fprintf(stderr, "%s: close error on %s: %s\n", + progname, tgt, strerror(errno)); + errcnt |= 04; + } + if (sflag) { + gettimeofday(&tv2, NULL); + getrusage(RUSAGE_SELF, &ru2); +#define tv2f(tv) ((tv).tv_sec + (float)(tv).tv_usec / 1000000) + f = tv2f(tv2) - tv2f(tv1); + s = (float)copied / (2<<19); + t = f ? s / f : s; + printf(" ****** %s File Information ******\n" + " Input file : %s\n" + " Output file : %s\n" + " Real Time (secs) : %14.6f\n" + " User Time (secs) : %14.6f\n" + " System Time (secs) : %14.6f\n" + " File Size (MB) : %14.6f\n" + " Transfer Rate (MB/s) : %14.6f\n", + progname, src, tgt, + f, + tv2f(ru2.ru_utime) - tv2f(ru1.ru_utime), + tv2f(ru2.ru_stime) - tv2f(ru1.ru_stime), + s, + t); + } +end1: + close(sfd); +} + +static void +ignoring(const char *type, const char *path) +{ + fprintf(stderr, "%s: %signoring %s %s\n", progname, +#if defined (SUS) + "", +#else /* !SUS */ + "warning: ", +#endif /* !SUS */ + type, path); +#if defined (SUS) + if (pers == PERS_MV) + errcnt |= 020; +#endif /* SUS */ +} + +static enum okay +do_unlink(const char *tgt, const struct stat *dsp) +{ + if (dsp && unlink(tgt) < 0) { + fprintf(stderr, "%s: cannot unlink %s\n%s: %s\n", + progname, tgt, + progname, strerror(errno)); + errcnt |= 01; + return STOP; + } + return OKAY; +} + +static void +devicecopy(const char *src, const struct stat *ssp, + const char *tgt, const struct stat *dsp) +{ + if (do_unlink(tgt, dsp) != OKAY) + return; + if (mknod(tgt, check_suid(ssp, ssp->st_mode & (07777|S_IFMT)), + ssp->st_rdev) < 0) { + fprintf(stderr, "%s: cannot create special file %s\n%s: %s\n", + progname, tgt, + progname, strerror(errno)); + errcnt |= 01; + return; + } + if (pflag) + permissions(tgt, ssp); +} + +static void +symlinkcopy(const char *src, const struct stat *ssp, + const char *tgt, const struct stat *dsp) +{ + static char *buf; + static size_t bufsize; + ssize_t sz; + + if (buf == NULL) + buf = smalloc(bufsize = 256); + for (;;) { + sz = readlink(src, buf, bufsize - 1); + if (sz < 0) { + fprintf(stderr, + "%s: cannot read symbolic link %s\n%s: %s\n", + progname, src, + progname, strerror(errno)); + errcnt |= 01; + return; + } + if (sz == bufsize - 1) { + buf = srealloc(buf, bufsize += 256); + continue; + } + buf[sz] = '\0'; + break; + } + if (do_unlink(tgt, dsp) != OKAY) + return; + if (symlink(buf, tgt) < 0) { + fprintf(stderr, "%s: cannot create symbolic link %s\n%s: %s\n", + progname, tgt, + progname, strerror(errno)); + errcnt |= 01; + return; + } + if (myuid == 0 && lchown(tgt, ssp->st_uid, ssp->st_gid) < 0) { +#if defined (SUS) + fprintf(stderr, + "%s: cannot change owner and group of %s\n%s: %s\n", + progname, tgt, + progname, strerror(errno)); +#endif /* SUS */ + if (pers != PERS_MV) + errcnt |= 010; + } +} + +static void +socketcopy(const char *src, const struct stat *ssp, + const char *tgt, const struct stat *dsp) +{ + int fd, addrsz; + struct sockaddr_un addr; + size_t len; + + if (do_unlink(tgt, dsp) != OKAY) + return; + len = strlen(tgt); + memset(&addr, 0, sizeof addr); + addr.sun_family = AF_UNIX; + addrsz = sizeof addr - sizeof addr.sun_path + len; + if ((len >= sizeof addr.sun_path ? errno = ENAMETOOLONG, fd = -1, 1 : + (strncpy(addr.sun_path,tgt,sizeof addr.sun_path), 0)) || + (fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0 || + bind(fd, (struct sockaddr *)&addr, addrsz) < 0) { + fprintf(stderr, "%s: cannot create socket %s\n%s: %s\n", + progname, tgt, + progname, strerror(errno)); + if (fd >= 0) + close(fd); + errcnt |= 01; + return; + } + close(fd); + if (pflag) + permissions(tgt, ssp); +} + +static void +specialcopy(const char *src, const struct stat *ssp, + const char *tgt, const struct stat *dsp) +{ + switch (ssp->st_mode & S_IFMT) { + case S_IFIFO: + case S_IFCHR: + case S_IFBLK: + case S_IFNAM: + case S_IFNWK: + devicecopy(src, ssp, tgt, dsp); + break; + case S_IFLNK: + symlinkcopy(src, ssp, tgt, dsp); + break; + case S_IFSOCK: + socketcopy(src, ssp, tgt, dsp); + break; + case S_IFDOOR: + ignoring("door", src); + break; + default: + fprintf(stderr, "%s: %s: unknown file type %o\n", + progname, src, (int)ssp->st_mode); + if (pers == PERS_MV) + errcnt |= 020; + } +} + +static void +getpath(const char *path, char **file, char **filend, size_t *sz, size_t *slen) +{ + *sz = 14 + strlen(path) + 2; + *file = smalloc(*sz); + *filend = *file; + if (path[0] == '/' && path[1] == '\0') + *(*filend)++ = '/'; + else { + register const char *cp = path; + while ((*(*filend)++ = *cp++) != '\0'); + (*filend)[-1] = '/'; + } + *slen = *filend - *file; +} + +static void +setpath(const char *base, char **file, char **filend, + size_t slen, size_t *sz, size_t *ss) +{ + if (slen + (*ss = strlen(base)) >= *sz) { + *sz += slen + *ss + 15; + *file = srealloc(*file, *sz); + *filend = &(*file)[slen]; + } + strcpy(*filend, base); +} + +static enum okay +trydelete(const char *path, int recursive) +{ + struct stat st; + enum okay val = OKAY; + + if (lstat(path, &st) < 0) { + fprintf(stderr, "%s: cannot stat %s for removal\n%s: %s\n", + progname, path, + progname, strerror(errno)); + errcnt |= 040; + val = STOP; + } else if ((st.st_mode & S_IFMT) == S_IFDIR) { + DIR *Dp; + + if (recursive == 0) + goto do_rmdir; + if ((Dp = opendir(path)) != NULL) { + struct dirent *dp; + char *copy, *cend; + size_t sz, slen, ss; + + getpath(path, &copy, &cend, &sz, &slen); + while ((dp = readdir(Dp)) != NULL) { + if (dp->d_name[0] == '.' && + (dp->d_name[1] == '\0' || + (dp->d_name[1] == '.' && + dp->d_name[2] == '\0'))) + continue; + setpath(dp->d_name, &copy, &cend, + slen, &sz, &ss); + if ((val = trydelete(copy, recursive)) == STOP) + break; + } + free(copy); + closedir(Dp); + if (val != STOP) { +do_rmdir: + if (rmdir(path) < 0) { + fprintf(stderr, + "%s: cannot remove directory %s\n%s: %s\n", + progname, path, + progname, strerror(errno)); + val = STOP; + } + } + } else { + fprintf(stderr, + "%s: cannot open directory %s for removal\n%s: %s\n", + progname, path, + progname, strerror(errno)); + errcnt |= 040; + val = STOP; + } + } else { + if (unlink(path) < 0) { + fprintf(stderr, "%s: cannot unlink %s\n%s: %s\n", + progname, path, + progname, strerror(errno)); + errcnt |= 040; + val = STOP; + } + } + return val; +} + +static enum okay +tryrename(const char *src, const struct stat *ssp, + const char *tgt, const struct stat *dsp) +{ + if (dsp && !fflag) { + if (iflag) { + fprintf(stderr, "%s: overwrite %s? ", + progname, tgt); + if (confirm() != OKAY) + return STOP; + } else if (ontty && (dsp->st_mode&S_IFMT) != S_IFLNK && + access(tgt, W_OK) < 0) { + fprintf(stderr, "%s: %s: %o mode? ", + progname, tgt, + (int)(dsp->st_mode & 0777)); + if (confirm() != OKAY) + return STOP; + } + } + if (rename(src, tgt) == 0) + return STOP; + if (errno != EXDEV) { + fprintf(stderr, "%s: cannot rename %s to %s\n%s: %s\n", + progname, src, tgt, + progname, strerror(errno)); + errcnt |= 01; + return STOP; + } + if (dsp) { + if ((dsp->st_mode & S_IFMT) == S_IFDIR && + (ssp->st_mode & S_IFMT) != S_IFDIR) { + fprintf(stderr, "%s: <%s> directory\n", + progname, tgt); + errcnt |= 01; + return STOP; + } + if ((dsp->st_mode & S_IFMT) != S_IFDIR && + (ssp->st_mode & S_IFMT) == S_IFDIR) { + fprintf(stderr, "%s: Target must be directory\n", + progname); + errcnt |= 01; + return STOP; + } + } + if (dsp == NULL || trydelete(tgt, 0) == OKAY) + return OKAY; + return STOP; +} + +static enum okay +commoncheck(const char *src, const char *tgt, const struct stat *dsp, + struct stat *ssp, + int (*statfn)(const char *, struct stat *)) +{ + if (statfn(src, ssp) < 0) { + if (pers == PERS_LN && sflag) + return OKAY; + fprintf(stderr, "%s: cannot access %s\n", progname, src); + errcnt |= 01; + return STOP; + } + if (dsp && (ssp->st_dev == dsp->st_dev && ssp->st_ino == dsp->st_ino)) { + fprintf(stderr, "%s: %s and %s are identical\n", + progname, src, tgt); + errcnt |= 01; + return STOP; + } + return OKAY; +} + +static void +cpmv(const char *src, const char *tgt, struct stat *dsp, int level, + int (*statfn)(const char *, struct stat *)) +{ + struct stat sst; + + if (commoncheck(src, tgt, dsp, &sst, + Rflag && level == 0 ? + pers == PERS_MV || HLPflag == 'P' ? + lstat : stat : + statfn) != OKAY) + return; + if (pers == PERS_MV && level == 0) { + if (tryrename(src, &sst, tgt, dsp) == STOP) + return; + dsp = NULL; + } + if ((sst.st_mode & S_IFMT) == S_IFDIR) { + DIR *Dp; + struct dirent *dp; + char *scp, *send, *dcp, *dend; + size_t ssz, slen, sss, dsz, dlen, dss; + int destcreat = 0; + + if (rflag == 0) { + fprintf(stderr, "%s: <%s> directory\n", + progname, src); + errcnt |= 01; + return; + } + if (dsp && (dsp->st_mode & S_IFMT) != S_IFDIR) { + fprintf(stderr, "%s: %s: Not a directory.\n", + progname, tgt); + errcnt |= 01; + return; + } +#if !defined (SUS) + if (pers == PERS_CP && dsp != NULL && iflag) { + fprintf(stderr, "%s: overwrite %s? ", + progname, tgt); + if (confirm() != OKAY) + return; + } +#endif /* !SUS */ + if (dsp == NULL) { + if (mkdir(tgt, check_suid(&sst, + sst.st_mode&07777 | S_IRWXU)) < 0) { + fprintf(stderr, "%s: %s: %s\n", + progname, tgt, strerror(errno)); + errcnt |= 01; + return; + } + destcreat = 1; + } + if ((Dp = opendir(src)) == NULL) { + fprintf(stderr, "%s: %s: %s\n", + progname, src, + strerror(errno)); + errcnt |= 01; + return; + } + getpath(src, &scp, &send, &ssz, &slen); + getpath(tgt, &dcp, &dend, &dsz, &dlen); + while ((dp = readdir(Dp)) != NULL) { + struct stat xst; + if (dp->d_name[0] == '.' && + (dp->d_name[1] == '\0' || + (dp->d_name[1] == '.' && + dp->d_name[2] == '\0'))) + continue; + setpath(dp->d_name, &scp, &send, slen, &ssz, &sss); + setpath(dp->d_name, &dcp, &dend, dlen, &dsz, &dss); + go(scp, dcp, stat(dcp, &xst) < 0 ? NULL : &xst, + level + 1, statfn); + } + free(scp); + free(dcp); + if (destcreat) + permissions(tgt, &sst); + closedir(Dp); + } else { + if (dsp != NULL && iflag) { + fprintf(stderr, "%s: overwrite %s? ", + progname, tgt); + if (confirm() != OKAY) + return; + } + if (dflag && sst.st_nlink > 1) { + if (canlink(tgt, &sst)) + return; + } + if ((sst.st_mode & S_IFMT) == S_IFREG || Rflag == 0) + filecopy(src, &sst, tgt, dsp); + else + specialcopy(src, &sst, tgt, dsp); + } + if (pers == PERS_MV && errcnt == 0 && level == 0) + trydelete(src, 1); + if ((pers == PERS_CP || pers == PERS_MV) && level == 0 && d0) + freedslots(); +} + +/*ARGSUSED3*/ +static void +ln(const char *src, const char *tgt, struct stat *dsp, int level, + int (*statfn)(const char *, struct stat *)) +{ + struct stat sst; + int (*how)(const char *, const char *) = sflag ? symlink : link; + + if (commoncheck(src, tgt, dsp, &sst, statfn) != OKAY) + return; + if ((sst.st_mode&S_IFMT) == S_IFDIR && !sflag) { + fprintf(stderr, "%s: <%s> directory\n", progname, src); + errcnt |= 01; + return; + } +#if (defined (SUS) || defined (S42)) && (defined (__linux__) || defined (__sun)) + if (sflag == 0) { + char *rpbuf = alloca(PATH_MAX+1); + if (realpath(src, rpbuf) == NULL) { + fprintf(stderr, "%s: cannot access %s\n", + progname, src); + errcnt |= 01; + return; + } + src = rpbuf; + } +#endif /* (SUS || S42) && (__linux__ || __sun) */ + if (dsp +#if !defined (SUS) + && !sflag +#endif /* !SUS */ + ) { + if (nflag && !fflag) { + fprintf(stderr, "%s: %s: File exists\n", + progname, tgt); + errcnt |= 01; + return; + } + if (!fflag && ontty && (dsp->st_mode&S_IFMT) != S_IFLNK && + access(tgt, W_OK) < 0) { + fprintf(stderr, "%s: %s: %o mode? ", + progname, tgt, (int)(dsp->st_mode & 0777)); + if (confirm() != OKAY) + return; + } + if (unlink(tgt) < 0) { + fprintf(stderr, "%s: cannot unlink %s\n%s: %s\n", + progname, tgt, + progname, strerror(errno)); + errcnt |= 01; + return; + } + } + if (how(src, tgt) < 0) { + if (sflag) + fprintf(stderr, "%s: cannot create %s\n%s: %s\n", + progname, tgt, + progname, strerror(errno)); + else if (errno == EXDEV) + fprintf(stderr, "%s: different file system\n", + progname); + else + fprintf(stderr, "%s: errno: %d no permission for %s\n", + progname, errno, tgt); + errcnt |= 01; + } +} + +static const char * +getfl(void) +{ + const char *optstring; + + if (progname[0] == 'm' && progname[1] == 'v') { + pers = PERS_MV; + optstring = "b:fi"; + dflag = pflag = rflag = Rflag = 1; + go = cpmv; + } else if (progname[0] == 'l' && progname[1] == 'n') { + pers = PERS_LN; + optstring = "fns"; +#if defined (SUS) + nflag = 1; +#endif /* SUS */ + go = ln; + } else { + pers = PERS_CP; + optstring = "ab:dDfiHLpPrRs"; + go = cpmv; + } + return optstring; +} + +int +main(int argc, char **argv) +{ + struct stat dst, ust; + const char *optstring; + int (*statfn)(const char *, struct stat *); + int i, illegal = 0; + +#ifdef __GLIBC__ + putenv("POSIXLY_CORRECT=1"); +#endif + progname = basename(argv[0]); + optstring = getfl(); + while ((i = getopt(argc, argv, optstring)) != EOF) { + switch (i) { + case 'b': + bflag = atol(optarg); + break; +#ifdef O_DIRECT + case 'D': + Dflag = 1; + break; +#endif /* O_DIRECT */ + case 'd': + dflag = 1; + break; + case 'f': + fflag = 1; +#if defined (SUS) + if (pers == PERS_MV) + iflag = 0; +#endif /* SUS */ + break; + case 'i': + iflag = 1; +#if defined (SUS) + if (pers == PERS_MV) + fflag = 0; +#endif /* SUS */ + break; + case 'n': + nflag = 1; + break; + case 'p': + pflag = 1; + break; + case 'a': + dflag = pflag = 1; + /*FALLTHRU*/ + case 'R': + Rflag = 1; + /*FALLTHRU*/ + case 'r': + rflag = 1; + break; + case 's': + sflag = 1; + break; + case 'H': + case 'L': + case 'P': + HLPflag = i; + break; + default: + illegal = 1; + } + } + argv += optind, argc -= optind; + if (argc < 2) { + fprintf(stderr, "%s: Insufficient arguments (%d)\n", + progname, argc); + illegal = 1; + } + if (illegal) + usage(); + umask(umsk = umask(0)); + ontty = isatty(0); +#if defined (SUS) + /* nothing */ +#elif defined (S42) + if (pers == PERS_MV && !ontty) + iflag = 0; +#else /* !SUS, !S42 */ + if (!ontty) + iflag = 0; +#endif /* !SUS, !S42 */ + myuid = geteuid(); + mygid = getegid(); + inull = scalloc(1, sizeof *inull); + inull->i_lln = inull->i_rln = inull; + statfn = (Rflag && HLPflag != 'L' +#if !defined (SUS) && !defined (S42) + || pers == PERS_LN +#endif /* !SUS && !S42 */ + ? lstat : stat); + if (lstat(argv[argc-1], &dst) == 0) { + if ((dst.st_mode&S_IFMT) != S_IFLNK || + stat(argv[argc-1], &ust) < 0) + ust = dst; + if ((ust.st_mode&S_IFMT) == S_IFDIR) { + char *copy, *cend; + size_t sz, slen, ss; + unsigned saverrs = errcnt; + + getpath(argv[argc-1], &copy, &cend, &sz, &slen); + for (i = 0; i < argc-1; i++) { + errcnt = 0; + setpath(basename(argv[i]), &copy, &cend, + slen, &sz, &ss); + go(argv[i], copy, statfn(copy, &dst) < 0 ? + NULL : &dst, 0, statfn); + saverrs |= errcnt; + } + errcnt = saverrs; + } else if (argc > 2) { + fprintf(stderr, "%s: Target must be directory\n", + progname); + usage(); + } else + go(argv[0], argv[1], pers == PERS_CP ? &ust : &dst, + 0, statfn); + } else if (argc > 2) { + fprintf(stderr, "%s: %s not found\n", progname, argv[argc-1]); + errcnt |= 01; + } else + go(argv[0], argv[1], NULL, 0, statfn); + return errcnt; +} diff --git a/cp/ln.1 b/cp/ln.1 @@ -0,0 +1,113 @@ +.\" +.\" Sccsid @(#)ln.1 1.11 (gritter) 2/2/05 +.\" Parts taken from ln(1), Unix 7th edition: +.\" Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" Redistributions of source code and documentation must retain the +.\" above copyright notice, this list of conditions and the following +.\" disclaimer. +.\" Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed or owned by Caldera +.\" International, Inc. +.\" Neither the name of Caldera International, Inc. nor the names of +.\" other contributors may be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA +.\" INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE +.\" LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.TH LN 1 "2/2/05" "Heirloom Toolchest" "User Commands" +.SH NAME +ln \- make a link +.SH SYNOPSIS +\fBln\fR [\fB\-f\fR] [\fB\-n\fR] [\fB\-s\fR] +\fIname1\fR [\fIname2\fR .\ .\ .\ ] \fItarget\fR +.SH DESCRIPTION +A link is a directory entry referring to a file; +the same file +(together with its size, all its protection information, etc.) +may have several links to it. +There is no way to distinguish a link to a file +from its original directory entry; +any changes in the file +are effective independently of the name +by which the file is known. +.PP +.B Ln +creates a link named +.I target +to an existing file +.IR name1 . +If +.I target +is a directory, +more than one name may be given, +and the links are placed in that directory, +with the name of the last pathname component. +.PP +It is forbidden to link to a directory +or to link across file systems. +It is, however, possible +to create a +.I symbolic +.I link +even in this case; +see the +.B \-s +option below. +.PP +The +.B ln +command accepts the following options: +.TP +.B \-f +If the target file exists, +an attempt is made to unlink it +before the new link is created, +regardless of file permissions. +This option is ignored with +.B /usr/5bin/ln +and +.B /usr/5bin/s42/ln +if the +.I \-s +option is also given. +.TP +.B \-n +Do not remove an existing target file +even if the user has write permission on it. +This is the default for +.B /usr/5bin/posix/ls +and +.BR /usr/5bin/posix2001/ls . +.TP +.B \-s +Create a symbolic link, +that is a special file containing the pathname of the target file. +The system will resolve this pathname +when the symbolic link is accessed. +A symbolic link can refer to all types of files +and span device boundaries, +but will become stale if the target file is removed. +An existing target file will not be overwritten. +.SH "SEE ALSO" +cp(1), +mv(1), +link(2), +symlink(2) diff --git a/cp/mkfile b/cp/mkfile @@ -0,0 +1,9 @@ +BIN = cp +OBJ = cp.o +LOCAL_CFLAGS = -DSUS +INSTALL_BIN = cp +INSTALL_MAN1 = cp.1 +DEPS = libcommon + +<$mkbuild/mk.default + diff --git a/cp/mv.1 b/cp/mv.1 @@ -0,0 +1,179 @@ +.\" +.\" Sccsid @(#)mv.1 1.15 (gritter) 1/24/05 +.\" Parts taken from cp(1) and mv(1), Unix 7th edition: +.\" Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" Redistributions of source code and documentation must retain the +.\" above copyright notice, this list of conditions and the following +.\" disclaimer. +.\" Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed or owned by Caldera +.\" International, Inc. +.\" Neither the name of Caldera International, Inc. nor the names of +.\" other contributors may be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA +.\" INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE +.\" LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.TH MV 1 "1/24/05" "Heirloom Toolchest" "User Commands" +.SH NAME +mv \- move or rename files and directories +.SH SYNOPSIS +\fBmv\fR [\fB\-f\fR] [\fB\-i\fR] [\fB\-b\ \fIsize\fR] +\fIfile1\fR [\fIfile2\fR .\ .\ .\ ] \fItarget\fR +.SH DESCRIPTION +.B Mv +moves (changes the name of) +.I file1 +to +.IR target . +If +.I target +is an existing regular file, +its content is overwritten. +Its mode and owner are preserved; +the mode of the source file is used otherwise. +If +the mode of +.I target +forbids writing +(and standard input is terminal for +.B /usr/5bin/mv +and +.BR /usr/5bin/s42/mv ), +.B mv +prints the mode +(see +.IR chmod (2)) +and reads the standard input +to obtain a line; +if the line begins with y, +the move takes place; +if not, +the file is not moved. +.PP +If +.I target +is a directory, +one or more files are copied +into the directory with their original file-names. +.PP +.B Mv +refuses to move a file onto itself. +.PP +The +.B mv +command accepts the following options: +.TP +.B \-f +.B Mv +will not ask for confirmation +even if the modes of the +.I target +file do not permit writing. +Overrides the +.B \-i +option in +.B /usr/5bin/posix/mv +and +.BR /usr/5bin/posix2001/mv . +.TP +.B \-i +.B mv +will ask for confirmation +before overwriting an existing target. +For +.B /usr/5bin/mv +and +.BR /usr/5bin/s42/mv , +this flag will be automatically disabled +if standard input is not a terminal. +Overrides the +.B \-f +option in +.B /usr/5bin/posix/mv +and +.BR /usr/5bin/posix2001/mv . +.PP +The following option is an extension: +.TP +\fB\-b\ \fIsize\fR +When a regular file is moved to another file system, +its data must be copied. +This option overrides the automatically determined +i/o buffer size for such copies; +.I size +is given in bytes. +.SH "SEE ALSO" +cp(1), +cat(1), +pr(1), +unlink(2) +.SH NOTES +Use either +.RS +.sp +.B mv +.B \-\- +.I \-file +.I target +.sp +.RE +or +.RS +.sp +.B mv +.I ./\-file +.I target +.sp +.RE +to move files that begin with a hyphen character. +.PP +If source and target +lie on different file systems, +.B mv +must copy the file and delete the original. +In this case +any linking relationship with other files is lost, +but +.B mv +will preserve linkage inside the moved tree. +.B Mv +will try to preserve access and modification times, +user and group ownerships, +and file permission bits. +Failing to preserve these modes +is not considered an error, +only +.B /usr/5bin/posix/mv +and +.B /usr/5bin/posix2001/mv +will print an error message. +Special files +such as block and character devices, +FIFOs, +and symbolic links +are recreated in the target hierarchy. +.PP +The pathname contained in a symbolic link +is not changed when the link is moved. +Symbolic links with relative pathnames +may thus change or lose their target +if moved to a different level in the file hierarchy. diff --git a/dc/dc.1 b/dc/dc.1 @@ -0,0 +1,231 @@ +.\" +.\" Sccsid @(#)dc.1 1.5 (gritter) 1/11/03 +.\" Derived from dc(1), Unix 7th edition: +.\" Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" Redistributions of source code and documentation must retain the +.\" above copyright notice, this list of conditions and the following +.\" disclaimer. +.\" Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed or owned by Caldera +.\" International, Inc. +.\" Neither the name of Caldera International, Inc. nor the names of +.\" other contributors may be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA +.\" INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE +.\" LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.TH DC 1 "1/11/03" "Heirloom Toolchest" "User Commands" +.SH NAME +dc \- desk calculator +.SH SYNOPSIS +\fBdc\fR [\fIfile\fR] +.SH DESCRIPTION +.I Dc +is an arbitrary precision arithmetic package. +Ordinarily it operates on decimal integers, +but one may specify an input base, output base, +and a number of fractional digits to be maintained. +The overall structure of +.I dc +is +a stacking (reverse Polish) calculator. +If an argument is given, +input is taken from that file until its end, +then from the standard input. +The following constructions are recognized: +.HP 6 +number +.br +The value of the number is pushed on the stack. +A number is an unbroken string of the digits 0-9. +It may be preceded by an underscore _ to input a +negative number. +Numbers may contain decimal points. +.HP 6 ++ \- / * % ^ +.br +The +top two values on the stack are added +(+), +subtracted +(\-), +multiplied (*), +divided (/), +remaindered (%), +or exponentiated (^). +The two entries are popped off the stack; +the result is pushed on the stack in their place. +Any fractional part of an exponent is ignored. +.TP +.BI s x +The +top of the stack is popped and stored into +a register named +.I x, +where +.I x +may be any character. +If +the +.B s +is capitalized, +.I x +is treated as a stack and the value is pushed on it. +.TP +.BI l x +The +value in register +.I x +is pushed on the stack. +The register +.I x +is not altered. +All registers start with zero value. +If the +.B l +is capitalized, +register +.I x +is treated as a stack and its top value is popped onto the main stack. +.TP +.B d +The +top value on the stack is duplicated. +.TP +.B p +The top value on the stack is printed. +The top value remains unchanged. +.B P +interprets the top of the stack as an ascii string, +removes it, and prints it. +.TP +.B f +All values on the stack and in registers are printed. +.TP +.B q +exits the program. +If executing a string, the recursion level is +popped by two. +If +.B q +is capitalized, +the top value on the stack is popped and the string execution level is popped +by that value. +.TP +.B x +treats the top element of the stack as a character string +and executes it as a string of dc commands. +.TP +.B X +replaces the number on the top of the stack with its scale factor. +.TP +.B "[ ... ]" +puts the bracketed ascii string onto the top of the stack. +.HP 6 +.I "<x >x =x" +.br +The +top two elements of the stack are popped and compared. +Register +.I x +is executed if they obey the stated +relation. +.TP +.B v +replaces the top element on the stack by its square root. +Any existing fractional part of the argument is taken +into account, but otherwise the scale factor is ignored. +.TP +.B ! +interprets the rest of the line as a UNIX command. +.TP +.B c +All values on the stack are popped. +.TP +.B i +The top value on the stack is popped and used as the +number radix for further input. +.B I +pushes the input base on the top of the stack. +.TP +.B o +The top value on the stack is popped and used as the +number radix for further output. +.TP +.SM +.B O +pushes the output base on the top of the stack. +.TP +.B k +the top of the stack is popped, and that value is used as +a non-negative scale factor: +the appropriate number of places +are printed on output, +and maintained during multiplication, division, and exponentiation. +The interaction of scale factor, +input base, and output base will be reasonable if all are changed +together. +.TP +.B z +The stack level is pushed onto the stack. +.TP +.SM +.B Z +replaces the number on the top of the stack with its length. +.TP +.B ? +A line of input is taken from the input source (usually the terminal) +and executed. +.TP +.B "; :" +are used by +.I bc +for array operations. +.PP +An example which prints the first ten values of n! is +.nf +.PP +.in +3 +[la1+dsa*pla10>y]sy +.br +0sa1 +.br +lyx +.fi +.SH "SEE ALSO" +bc(1), +which is a preprocessor for +.I dc +providing infix notation and a C-like syntax +which implements functions and reasonable control +structures for programs. +.SH DIAGNOSTICS +`x is unimplemented' where x is an octal number. +.br +`stack empty' for not enough elements on the stack to do what was asked. +.br +`Out of space' when the free list is exhausted (too many digits). +.br +`Out of headers' for too many numbers being kept around. +.br +`Out of pushdown' for too many items on the stack. +.br +`Nesting Depth' for too many levels of nested execution. diff --git a/dc/dc.c b/dc/dc.c @@ -0,0 +1,2061 @@ +/* from 4.4BSD /usr/src/usr.bin/dc/dc.c */ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This module is believed to contain source code proprietary to AT&T. + * Use and redistribution is subject to the Berkeley Software License + * Agreement and your Software Agreement with AT&T (Western Electric). + * + * from dc.c 8.1 (Berkeley) 6/6/93" + */ +/* + * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * Redistributions of source code and documentation must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed or owned by Caldera + * International, Inc. + * Neither the name of Caldera International, Inc. nor the names of + * other contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA + * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE + * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* Sccsid @(#)dc.c 1.21 (gritter) 12/25/06> */ + +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include <stdio.h> +#include <signal.h> +#include "sigset.h" +#include <stdlib.h> +#include <inttypes.h> +#include <limits.h> + +#include "dc.h" + +int +main(int argc,char **argv) +{ + init(argc,argv); + commnds(); + /*NOTREACHED*/ + return(0); +} + +void +commnds(void){ + register int c; + register struct blk *p,*q; + long l; + int sign; + struct blk **ptr,*s,*t; + struct sym *sp; + int sk,sk1,sk2; + int n,d; + + while(1){ + if(((c = readc())>='0' && c <= '9')|| (c>='A' && c <='F') || c == '.'){ + unreadc(c); + p = readin(); + pushp(p); + continue; + } + switch(c){ + case ' ': + case '\n': + case 0377: + case EOF: + continue; + case 'Y': + sdump("stk",*stkptr); + printf("all %ld rel %ld headmor %ld\n",all,rel,headmor); + printf("nbytes %ld\n",nbytes); + continue; + case '_': + p = readin(); + savk = sunputc(p); + chsign(p); + sputc(p,savk); + pushp(p); + continue; + case '-': + subt(); + continue; + case '+': + if(eqk() != 0)continue; + binop('+'); + continue; + case '*': + arg1 = pop(); + EMPTY; + arg2 = pop(); + EMPTYR(arg1); + sk1 = sunputc(arg1); + sk2 = sunputc(arg2); + binop('*'); + p = pop(); + sunputc(p); + savk = n = sk1+sk2; + if(n>k && n>sk1 && n>sk2){ + sk = sk1; + if(sk<sk2)sk = sk2; + if(sk<k)sk = k; + p = removc(p,n-sk); + savk = sk; + } + sputc(p,savk); + pushp(p); + continue; + case '/': +casediv: + if(dscale() != 0)continue; + binop('/'); + if(irem != 0)release(irem); + release(rem); + continue; + case '%': + if(dscale() != 0)continue; + binop('/'); + p = pop(); + release(p); + if(irem == 0){ + sputc(rem,skr+k); + pushp(rem); + continue; + } + p = add0(rem,skd-(skr+k)); + q = add(p,irem); + release(p); + release(irem); + sputc(q,skd); + pushp(q); + continue; + case 'v': + p = pop(); + EMPTY; + savk = sunputc(p); + if(length(p) == 0){ + sputc(p,savk); + pushp(p); + continue; + } + if((c = sbackc(p))<0){ + error("sqrt of neg number\n"); + } + if(k<savk)n = savk; + else{ + n = k*2-savk; + savk = k; + } + arg1 = add0(p,n); + arg2 = dcsqrt(arg1); + sputc(arg2,savk); + pushp(arg2); + continue; + case '^': + neg = 0; + arg1 = pop(); + EMPTY; + if(sunputc(arg1) != 0)error("exp not an integer\n"); + arg2 = pop(); + EMPTYR(arg1); + if(sfbeg(arg1) == 0 && sbackc(arg1)<0){ + neg++; + chsign(arg1); + } + if(length(arg1)>=3){ + error("exp too big\n"); + } + savk = sunputc(arg2); + p = dcexp(arg2,arg1); + release(arg2); + rewind(arg1); + c = sgetc(arg1); + if(sfeof(arg1) == 0) + c = sgetc(arg1)*100 + c; + d = c*savk; + release(arg1); + if(neg == 0){ + if(k>=savk)n = k; + else n = savk; + if(n<d){ + q = removc(p,d-n); + sputc(q,n); + pushp(q); + } + else { + sputc(p,d); + pushp(p); + } + } + else { + sputc(p,d); + pushp(p); + } + if(neg == 0)continue; + p = pop(); + q = salloc(2); + sputc(q,1); + sputc(q,0); + pushp(q); + pushp(p); + goto casediv; + case 'z': + p = salloc(2); + n = stkptr - stkbeg; + if(n >= 100){ + sputc(p,n/100); + n %= 100; + } + sputc(p,n); + sputc(p,0); + pushp(p); + continue; + case 'Z': + p = pop(); + EMPTY; + n = (length(p)-1)<<1; + fsfile(p); + sbackc(p); + if(sfbeg(p) == 0){ + if((c = sbackc(p))<0){ + n -= 2; + if(sfbeg(p) == 1)n += 1; + else { + if((c = sbackc(p)) == 0)n += 1; + else if(c > 90)n -= 1; + } + } + else if(c < 10) n -= 1; + } + release(p); + q = salloc(1); + if(n >= 100){ + sputc(q,n%100); + n /= 100; + } + sputc(q,n); + sputc(q,0); + pushp(q); + continue; + case 'i': + p = pop(); + EMPTY; + p = scalint(p); + release(inbas); + inbas = p; + continue; + case 'I': + p = copy(inbas,length(inbas)+1); + sputc(p,0); + pushp(p); + continue; + case 'o': + p = pop(); + EMPTY; + p = scalint(p); + sign = 0; + n = length(p); + q = copy(p,n); + fsfile(q); + l = c = sbackc(q); + if(n != 1){ + if(c<0){ + sign = 1; + chsign(q); + n = length(q); + fsfile(q); + l = c = sbackc(q); + } + if(n != 1){ + while(sfbeg(q) == 0)l = l*100+sbackc(q); + } + } + if (l > BC_BASE_MAX) + error("output base is too large\n"); + logo = log_2(l); + obase = l; + release(basptr); + if(sign == 1)obase = (long)-l; + basptr = p; + outdit = (int (*)(struct blk *, int, int))bigot; + if(n == 1 && sign == 0){ + if(c <= 16){ + outdit = (int (*)(struct blk *, int, int))hexot; + fw = 1; + fw1 = 0; + ll = 68; + release(q); + continue; + } + } + n = 0; + if(sign == 1)n++; + p = salloc(1); + sputc(p,-1); + t = add(p,q); + n += length(t)*2; + fsfile(t); + if((c = sbackc(t))>9)n++; + release(t); + release(q); + release(p); + fw = n; + fw1 = n-1; + ll = 68; + if(fw>=ll)continue; + ll = (68/fw)*fw; + continue; + case 'O': + p = copy(basptr,length(basptr)+1); + sputc(p,0); + pushp(p); + continue; + case '[': + n = 0; + p = salloc(0); + while(1){ + if((c = readc()) == ']'){ + if(n == 0)break; + n--; + } + sputc(p,c); + if(c == '[')n++; + } + pushp(p); + continue; + case 'k': + p = pop(); + EMPTY; + p = scalint(p); + if(length(p)>1){ + error("scale too big\n"); + } + rewind(p); + k = sfeof(p)?0:sgetc(p); + release(scalptr); + scalptr = p; + continue; + case 'K': + p = copy(scalptr,length(scalptr)+1); + sputc(p,0); + pushp(p); + continue; + case 'X': + p = pop(); + EMPTY; + fsfile(p); + n = sbackc(p); + release(p); + p = salloc(2); + sputc(p,n); + sputc(p,0); + pushp(p); + continue; + case 'Q': + p = pop(); + EMPTY; + if(length(p)>2){ + error("Q?\n"); + } + rewind(p); + if((c = sgetc(p))<0){ + error("neg Q\n"); + } + release(p); + while(c-- > 0){ + if(readptr == &readstk[0]){ + error("readstk?\n"); + } + if(*readptr != 0)release(*readptr); + readptr--; + } + continue; + case 'q': + if(readptr <= &readstk[1])exit(0); + if(*readptr != 0)release(*readptr); + readptr--; + if(*readptr != 0)release(*readptr); + readptr--; + continue; + case 'f': + if(stkptr == &stack[0])printf("empty stack\n"); + else { + for(ptr = stkptr; ptr > &stack[0];){ + print(*ptr--); + } + } + continue; + case 'p': + if(stkptr == &stack[0])printf("empty stack\n"); + else{ + print(*stkptr); + } + continue; + case 'P': + p = pop(); + EMPTY; + sputc(p,0); + printf("%s",p->beg); + release(p); + continue; + case 'd': + if(stkptr == &stack[0]){ + printf("empty stack\n"); + continue; + } + q = *stkptr; + n = length(q); + p = copy(*stkptr,n); + pushp(p); + continue; + case 'c': + while(stkerr == 0){ + p = pop(); + if(stkerr == 0)release(p); + } + continue; + case 'S': + if(stkptr == &stack[0]){ + error("save: args\n"); + } + c = readc() & 0377; + sptr = stable[c]; + sp = stable[c] = sfree; + sfree = sfree->next; + if(sfree == 0)goto sempty; + sp->next = sptr; + p = pop(); + EMPTY; + if(c >= ARRAYST){ + q = copy(p,length(p)); + for(n = 0;n < PTRSZ;n++)sputc(q,0); + release(p); + p = q; + } + sp->val = p; + continue; +sempty: + error("symbol table overflow\n"); + case 's': + if(stkptr == &stack[0]){ + error("save:args\n"); + } + c = readc() & 0377; + sptr = stable[c]; + if(sptr != 0){ + p = sptr->val; + if(c >= ARRAYST){ + rewind(p); + while(sfeof(p) == 0)release(dcgetwd(p)); + } + release(p); + } + else{ + sptr = stable[c] = sfree; + sfree = sfree->next; + if(sfree == 0)goto sempty; + sptr->next = 0; + } + p = pop(); + sptr->val = p; + continue; + case 'l': + load(); + continue; + case 'L': + c = readc() & 0377; + sptr = stable[c]; + if(sptr == 0){ + error("L?\n"); + } + stable[c] = sptr->next; + sptr->next = sfree; + sfree = sptr; + p = sptr->val; + if(c >= ARRAYST){ + rewind(p); + while(sfeof(p) == 0){ + q = dcgetwd(p); + if(q != 0)release(q); + } + } + pushp(p); + continue; + case ':': + p = pop(); + EMPTY; + q = scalint(p); + fsfile(q); + c = 0; + if((sfbeg(q) == 0) && ((c = sbackc(q))<0)){ + error("neg index\n"); + } + if(length(q)>2){ + error("index too big\n"); + } + if(sfbeg(q) == 0)c = c*100+sbackc(q); + if(c >= BC_DIM_MAX){ + error("index too big\n"); + } + release(q); + n = readc() & 0377; + sptr = stable[n]; + if(sptr == 0){ + sptr = stable[n] = sfree; + sfree = sfree->next; + if(sfree == 0)goto sempty; + sptr->next = 0; + p = salloc((c+PTRSZ)*PTRSZ); + zero(p); + } + else{ + p = sptr->val; + if(length(p)-PTRSZ < c*PTRSZ){ + q = copy(p,(c+PTRSZ)*PTRSZ); + release(p); + p = q; + } + } + seekc(p,c*PTRSZ); + q = lookwd(p); + if (q!=NULL) release(q); + s = pop(); + EMPTY; + salterwd((struct wblk *)p,s); + sptr->val = p; + continue; + case ';': + p = pop(); + EMPTY; + q = scalint(p); + fsfile(q); + c = 0; + if((sfbeg(q) == 0) && ((c = sbackc(q))<0)){ + error("neg index\n"); + } + if(length(q)>2){ + error("index too big\n"); + } + if(sfbeg(q) == 0)c = c*100+sbackc(q); + if(c >= BC_DIM_MAX){ + error("index too big\n"); + } + release(q); + n = readc() & 0377; + sptr = stable[n]; + if(sptr != 0){ + p = sptr->val; + if(length(p)-PTRSZ >= c*PTRSZ){ + seekc(p,c*PTRSZ); + s = dcgetwd(p); + if(s != 0){ + q = copy(s,length(s)); + pushp(q); + continue; + } + } + } + q = salloc(1); + sputc(q, 0); + pushp(q); + continue; + case 'x': +execute: + p = pop(); + EMPTY; + if((readptr != &readstk[0]) && (*readptr != 0)){ + if((*readptr)->rd == (*readptr)->wt) + release(*readptr); + else{ + if(readptr++ == &readstk[RDSKSZ]){ + error("nesting depth\n"); + } + } + } + else readptr++; + *readptr = p; + if(p != 0)rewind(p); + else{ + if((c = readc()) != '\n')unreadc(c); + } + continue; + case '?': + if(++readptr == &readstk[RDSKSZ]){ + error("nesting depth\n"); + } + *readptr = 0; + fsave = curfile; + curfile = stdin; + while((c = readc()) == '!')command(); + p = salloc(0); + sputc(p,c); + while((c = readc()) != '\n'){ + sputc(p,c); + if(c == '\\')sputc(p,readc()); + } + curfile = fsave; + *readptr = p; + continue; + case '!': + if(command() == 1)goto execute; + continue; + case '<': + case '>': + case '=': + if(cond(c) == 1)goto execute; + continue; + default: + printf("%o is unimplemented\n",c); + } + } +} + +struct blk * +div(struct blk *ddivd,struct blk *ddivr) +{ + int divsign,remsign,offset,divcarry = 0; + int carry, dig = 0,magic,d = 0,dd; + long c,td,cc; + struct blk *ps; + register struct blk *p,*divd,*divr; + + rem = 0; + p = salloc(0); + if(length(ddivr) == 0){ + pushp(ddivr); + printf("divide by 0\n"); + return NULL; + } + divsign = remsign = 0; + divr = ddivr; + fsfile(divr); + if(sbackc(divr) == -1){ + divr = copy(ddivr,length(ddivr)); + chsign(divr); + divsign = ~divsign; + } + divd = copy(ddivd,length(ddivd)); + fsfile(divd); + if(sfbeg(divd) == 0 && sbackc(divd) == -1){ + chsign(divd); + divsign = ~divsign; + remsign = ~remsign; + } + offset = length(divd) - length(divr); + if(offset < 0)goto ddone; + seekc(p,offset+1); + sputc(divd,0); + magic = 0; + fsfile(divr); + c = sbackc(divr); + if(c<10)magic++; + c = c*100 + (sfbeg(divr)?0:sbackc(divr)); + if(magic>0){ + c = (c*100 +(sfbeg(divr)?0:sbackc(divr)))*2; + c /= 25; + } + while(offset >= 0){ + fsfile(divd); + td = sbackc(divd)*100; + dd = sfbeg(divd)?0:sbackc(divd); + td = (td+dd)*100; + dd = sfbeg(divd)?0:sbackc(divd); + td = td+dd; + cc = c; + if(offset == 0)td += 1; + else cc += 1; + if(magic != 0)td = td<<3; + dig = td/cc; + rewind(divr); + rewind(divxyz); + carry = 0; + while(sfeof(divr) == 0){ + d = sgetc(divr)*dig+carry; + carry = d / 100; + salterc(divxyz,d%100); + } + salterc(divxyz,carry); + rewind(divxyz); + seekc(divd,offset); + carry = 0; + while(sfeof(divd) == 0){ + d = slookc(divd); + d = d-(sfeof(divxyz)?0:sgetc(divxyz))-carry; + carry = 0; + if(d < 0){ + d += 100; + carry = 1; + } + salterc(divd,d); + } + divcarry = carry; + sbackc(p); + salterc(p,dig); + sbackc(p); + if(--offset >= 0){ + if(d > 0){ + sbackc(divd); + dd=sbackc(divd); + salterc(divd,dd+100); + } + divd->wt--; + } + } + if(divcarry != 0){ + salterc(p,dig-1); + salterc(divd,-1); + ps = add(divr,divd); + release(divd); + divd = ps; + } + + rewind(p); + divcarry = 0; + while(sfeof(p) == 0){ + d = slookc(p)+divcarry; + divcarry = 0; + if(d >= 100){ + d -= 100; + divcarry = 1; + } + salterc(p,d); + } + if(divcarry != 0)salterc(p,divcarry); + fsfile(p); + while(sfbeg(p) == 0){ + if(sbackc(p) == 0)truncate(p); + else break; + } + if(divsign < 0)chsign(p); + fsfile(divd); + while(sfbeg(divd) == 0){ + if(sbackc(divd) == 0)truncate(divd); + else break; + } +ddone: + if(remsign<0)chsign(divd); + if(divr != ddivr)release(divr); + rem = divd; + return(p); +} + +int +dscale(void){ + register struct blk *dd,*dr; + register struct blk *r; + int c; + + dr = pop(); + EMPTYS; + dd = pop(); + EMPTYSR(dr); + fsfile(dd); + skd = sunputc(dd); + fsfile(dr); + skr = sunputc(dr); + if(sfbeg(dr) == 1 || (sfbeg(dr) == 0 && sbackc(dr) == 0)){ + sputc(dr,skr); + pushp(dr); + errorrt("divide by 0\n"); + } + c = k-skd+skr; + if(c < 0)r = removr(dd,-c); + else { + r = add0(dd,c); + irem = 0; + } + arg1 = r; + arg2 = dr; + savk = k; + return(0); +} + +struct blk * +removr(struct blk *p,int n) +{ + int nn; + register struct blk *q,*s,*r; + + rewind(p); + nn = (n+1)/2; + q = salloc(nn); + while(n>1){ + sputc(q,sgetc(p)); + n -= 2; + } + r = salloc(2); + while(sfeof(p) == 0)sputc(r,sgetc(p)); + release(p); + if(n == 1){ + s = dcdiv(r,tenptr); + release(r); + rewind(rem); + if(sfeof(rem) == 0)sputc(q,sgetc(rem)); + release(rem); + irem = q; + return(s); + } + irem = q; + return(r); +} + +struct blk * +sqrt(struct blk *p) +{ + struct blk *t; + struct blk *r,*q,*s; + int c,n,nn; + + n = length(p); + fsfile(p); + c = sbackc(p); + if((n&1) != 1)c = c*100+(sfbeg(p)?0:sbackc(p)); + n = (n+1)>>1; + r = salloc(n); + zero(r); + seekc(r,n); + nn=1; + while((c -= nn)>=0)nn+=2; + c=(nn+1)>>1; + fsfile(r); + sbackc(r); + if(c>=100){ + c -= 100; + salterc(r,c); + sputc(r,1); + } + else salterc(r,c); + while(1){ + q = dcdiv(p,r); + s = add(q,r); + release(q); + release(rem); + q = dcdiv(s,sqtemp); + release(s); + release(rem); + s = copy(r,length(r)); + chsign(s); + t = add(s,q); + release(s); + fsfile(t); + nn = sfbeg(t)?0:sbackc(t); + if(nn>=0)break; + release(r); + release(t); + r = q; + } + release(t); + release(q); + release(p); + return(r); +} + +struct blk * +exp(struct blk *base,struct blk *ex) +{ + register struct blk *r,*e,*p; + struct blk *e1,*t,*cp; + int temp,c,n; + r = salloc(1); + sputc(r,1); + p = copy(base,length(base)); + e = copy(ex,length(ex)); + fsfile(e); + if(sfbeg(e) != 0)goto edone; + temp=0; + c = sbackc(e); + if(c<0){ + temp++; + chsign(e); + } + while(length(e) != 0){ + e1=dcdiv(e,sqtemp); + release(e); + e = e1; + n = length(rem); + release(rem); + if(n != 0){ + e1=mult(p,r); + release(r); + r = e1; + } + t = copy(p,length(p)); + cp = mult(p,t); + release(p); + release(t); + p = cp; + } + if(temp != 0){ + if((c = length(base)) == 0){ + goto edone; + } + if(c>1)create(r); + else{ + rewind(base); + if((c = sgetc(base))<=1){ + create(r); + sputc(r,c); + } + else create(r); + } + } +edone: + release(p); + release(e); + return(r); +} + +void +init(int argc,char **argv) +{ + register struct sym *sp; + + if (sigset(SIGINT, SIG_IGN) != SIG_IGN) + sigset(SIGINT,onintr); + setbuf(stdout,(char *)NULL); + svargc = --argc; + svargv = argv; + while(svargc>0 && svargv[1][0] == '-'){ + switch(svargv[1][1]){ + default: + dbg=1; + } + svargc--; + svargv++; + } + ifile=1; + if(svargc<=0)curfile = stdin; + else if((curfile = fopen(svargv[1],"r")) == NULL){ + printf("can't open file %s\n",svargv[1]); + exit(1); + } + scalptr = salloc(1); + sputc(scalptr,0); + basptr = salloc(1); + sputc(basptr,10); + obase=10; + log_10=log_2(10L); + ll=68; + fw=1; + fw1=0; + tenptr = salloc(1); + sputc(tenptr,10); + obase=10; + inbas = salloc(1); + sputc(inbas,10); + sqtemp = salloc(1); + sputc(sqtemp,2); + chptr = salloc(0); + strptr = salloc(0); + divxyz = salloc(0); + stkbeg = stkptr = &stack[0]; + stkend = &stack[STKSZ]; + stkerr = 0; + readptr = &readstk[0]; + k=0; + sp = sptr = &symlst[0]; + while(sptr < &symlst[TBLSZ]){ + sptr->next = ++sp; + sptr++; + } + sptr->next=0; + sfree = &symlst[0]; + return; +} + +void +onintr(int signum){ + + sigset(SIGINT,onintr); + while(readptr != &readstk[0]){ + if(*readptr != 0){release(*readptr);} + readptr--; + } + curfile = stdin; + commnds(); +} + +void +pushp(struct blk *p) +{ + if(stkptr == stkend){ + printf("out of stack space\n"); + return; + } + stkerr=0; + *++stkptr = p; + return; +} + +struct blk * +pop(void){ + if(stkptr == stack){ + stkerr=1; + return(0); + } + return(*stkptr--); +} + +struct blk * +readin(void){ + register struct blk *p,*q; + int dp,dpct; + register int c; + + dp = dpct=0; + p = salloc(0); + while(1){ + c = readc(); + switch(c){ + case '.': + if(dp != 0){ + unreadc(c); + break; + } + dp++; + continue; + case '\\': + readc(); + continue; + default: + if(c >= 'A' && c <= 'F')c = c - 'A' + 10; + else if(c >= '0' && c <= '9')c -= '0'; + else goto gotnum; + if(dp != 0){ + if(dpct >= 99)continue; + dpct++; + } + create(chptr); + if(c != 0)sputc(chptr,c); + q = mult(p,inbas); + release(p); + p = add(chptr,q); + release(q); + } + } +gotnum: + unreadc(c); + if(dp == 0){ + sputc(p,0); + return(p); + } + else{ + q = scale(p,dpct); + return(q); + } +} + +struct blk * +add0(struct blk *p,int ct) +{ + /* returns pointer to struct with ct 0's & p */ + register struct blk *q,*t; + + q = salloc(length(p)+(ct+1)/2); + while(ct>1){ + sputc(q,0); + ct -= 2; + } + rewind(p); + while(sfeof(p) == 0){ + sputc(q,sgetc(p)); + } + release(p); + if(ct == 1){ + t = mult(tenptr,q); + release(q); + return(t); + } + return(q); +} + +struct blk * +mult(struct blk *p,struct blk *q) +{ + register struct blk *mp,*mq,*mr; + int sign,offset,carry; + int cq,cp,mt,mcr; + + offset = sign = 0; + fsfile(p); + mp = p; + if(sfbeg(p) == 0){ + if(sbackc(p)<0){ + mp = copy(p,length(p)); + chsign(mp); + sign = ~sign; + } + } + fsfile(q); + mq = q; + if(sfbeg(q) == 0){ + if(sbackc(q)<0){ + mq = copy(q,length(q)); + chsign(mq); + sign = ~sign; + } + } + mr = salloc(length(mp)+length(mq)); + zero(mr); + rewind(mq); + while(sfeof(mq) == 0){ + cq = sgetc(mq); + rewind(mp); + rewind(mr); + mr->rd += offset; + carry=0; + while(sfeof(mp) == 0){ + cp = sgetc(mp); + mcr = sfeof(mr)?0:slookc(mr); + mt = cp*cq + carry + mcr; + carry = mt/100; + salterc(mr,mt%100); + } + offset++; + if(carry != 0){ + mcr = sfeof(mr)?0:slookc(mr); + salterc(mr,mcr+carry); + } + } + if(sign < 0){ + chsign(mr); + } + if(mp != p)release(mp); + if(mq != q)release(mq); + return(mr); +} + +void +chsign(struct blk *p) +{ + register int carry; + register char ct; + + carry=0; + rewind(p); + while(sfeof(p) == 0){ + ct=100-slookc(p)-carry; + carry=1; + if(ct>=100){ + ct -= 100; + carry=0; + } + salterc(p,ct); + } + if(carry != 0){ + sputc(p,-1); + fsfile(p); + sbackc(p); + ct = sbackc(p); + if(ct == 99){ + truncate(p); + sputc(p,-1); + } + } + else{ + fsfile(p); + ct = sbackc(p); + if(ct == 0)truncate(p); + } + return; +} + +int +readc(void){ +loop: + if((readptr != &readstk[0]) && (*readptr != 0)){ + if(sfeof(*readptr) == 0)return(lastchar = sgetc(*readptr)); + release(*readptr); + readptr--; + goto loop; + } + lastchar = getc(curfile); + if(lastchar != EOF)return(lastchar); + if(readptr != &readptr[0]){ + readptr--; + if(*readptr == 0)curfile = stdin; + goto loop; + } + if(curfile != stdin){ + fclose(curfile); + curfile = stdin; + goto loop; + } + exit(0); +} + +void +unreadc(char c) +{ + + if((readptr != &readstk[0]) && (*readptr != 0)){ + sungetc(*readptr,c); + } + else ungetc(c,curfile); + return; +} + +void +binop(char c) +{ + register struct blk *r = NULL; + + switch(c){ + case '+': + r = add(arg1,arg2); + break; + case '*': + r = mult(arg1,arg2); + break; + case '/': + r = dcdiv(arg1,arg2); + break; + } + release(arg1); + release(arg2); + sputc(r,savk); + pushp(r); + return; +} + +void +print(struct blk *hptr) +{ + int sc; + register struct blk *p,*q,*dec; + int dig,dout,ct; + + rewind(hptr); + while(sfeof(hptr) == 0){ + if(sgetc(hptr)>99){ + rewind(hptr); + while(sfeof(hptr) == 0){ + printf("%c",sgetc(hptr)); + } + printf("\n"); + return; + } + } + fsfile(hptr); + sc = sbackc(hptr); + if(sfbeg(hptr) != 0){ + printf("0\n"); + return; + } + count = ll; + p = copy(hptr,length(hptr)); + sunputc(p); + fsfile(p); + if(sbackc(p)<0){ + chsign(p); + OUTC('-'); + } + if((obase == 0) || (obase == -1)){ + oneot(p,sc,'d'); + return; + } + if(obase == 1){ + oneot(p,sc,'1'); + return; + } + if(obase == 10){ + tenot(p,sc); + return; + } + create(strptr); + dig = log_10*sc; + dout = ((dig/10) + dig) /logo; + dec = getdec(p,sc); + p = removc(p,sc); + while(length(p) != 0){ + q = dcdiv(p,basptr); + release(p); + p = q; + (*outdit)(rem,0,1); + } + release(p); + fsfile(strptr); + while(sfbeg(strptr) == 0)OUTC(sbackc(strptr)); + if(sc == 0){ + release(dec); + printf("\n"); + return; + } + create(strptr); + OUTC('.'); + ct=0; + do{ + q = mult(basptr,dec); + release(dec); + dec = getdec(q,sc); + p = removc(q,sc); + (*outdit)(p,1,ct+1<dout); + }while(++ct < dout); + release(dec); + rewind(strptr); + while(sfeof(strptr) == 0)OUTC(sgetc(strptr)); + printf("\n"); + return; +} + +struct blk * +getdec(struct blk *p,int sc) +{ + int cc; + register struct blk *q,*t,*s; + + rewind(p); + if(length(p)*2 < sc){ + q = copy(p,length(p)); + return(q); + } + q = salloc(length(p)); + while(sc >= 1){ + sputc(q,sgetc(p)); + sc -= 2; + } + if(sc != 0){ + t = mult(q,tenptr); + s = salloc(cc = length(q)); + release(q); + rewind(t); + while(cc-- > 0)sputc(s,sgetc(t)); + sputc(s,0); + release(t); + t = dcdiv(s,tenptr); + release(s); + release(rem); + return(t); + } + return(q); +} + +void +tenot(struct blk *p,int sc) +{ + register int c,f; + char b[3]; + + fsfile(p); + f=0; + while((sfbeg(p) == 0) && ((p->rd-p->beg-1)*2 >= sc)){ + c = sbackc(p); + if((c<10) && (f == 1))snprintf(b, sizeof b, "0%d",c); + else snprintf(b, sizeof b, "%d",c); + f=1; + TEST2(b); + } + if(sc == 0){ + printf("\n"); + release(p); + return; + } + if((p->rd-p->beg)*2 > sc){ + c = sbackc(p); + snprintf(b, sizeof b, "%d.",c/10); + TEST2(b); + OUTC(c%10 +'0'); + sc--; + } + else { + OUTC('.'); + } + if(sc > (p->rd-p->beg)*2){ + while(sc>(p->rd-p->beg)*2){ + OUTC('0'); + sc--; + } + } + while(sc > 1){ + c = sbackc(p); + if(c<10)snprintf(b, sizeof b, "0%d",c); + else snprintf(b, sizeof b, "%d",c); + sc -= 2; + TEST2(b); + } + if(sc == 1){ + OUTC(sbackc(p)/10 +'0'); + } + printf("\n"); + release(p); + return; +} + +void +oneot(struct blk *p,int sc,char ch) +{ + register struct blk *q; + + q = removc(p,sc); + create(strptr); + sputc(strptr,-1); + while(length(q)>0){ + p = add(strptr,q); + release(q); + q = p; + OUTC(ch); + } + release(q); + printf("\n"); + return; +} + +void +hexot(struct blk *p,int flg,int unused) +{ + register int c; + rewind(p); + if(sfeof(p) != 0){ + sputc(strptr,'0'); + release(p); + return; + } + c = sgetc(p); + release(p); + if(c >= 16){ + printf("hex digit > 16"); + return; + } + sputc(strptr,c<10?c+'0':c-10+'A'); + return; +} + +void +bigot(struct blk *p,int flg,int putspc) +{ + register struct blk *t,*q; + register int l = 0; + int neg; + + if(flg == 1)t = salloc(0); + else{ + t = strptr; + l = length(strptr)+fw-1; + } + neg=0; + if(length(p) != 0){ + fsfile(p); + if(sbackc(p)<0){ + neg=1; + chsign(p); + } + while(length(p) != 0){ + q = dcdiv(p,tenptr); + release(p); + p = q; + rewind(rem); + sputc(t,sfeof(rem)?'0':sgetc(rem)+'0'); + release(rem); + } + } + release(p); + if(flg == 1){ + l = fw1-length(t); + if(neg != 0){ + l--; + sputc(strptr,'-'); + } + fsfile(t); + while(l-- > 0)sputc(strptr,'0'); + while(sfbeg(t) == 0)sputc(strptr,sbackc(t)); + release(t); + } + else{ + l -= length(strptr); + while(l-- > 0)sputc(strptr,'0'); + if(neg != 0){ + sunputc(strptr); + sputc(strptr,'-'); + } + } + if (putspc) + sputc(strptr,' '); + return; +} + +struct blk * +add(struct blk *a1,struct blk *a2) +{ + register struct blk *p; + register int carry,n; + int size; + int c = 0,n1,n2; + + size = length(a1)>length(a2)?length(a1):length(a2); + p = salloc(size); + rewind(a1); + rewind(a2); + carry=0; + while(--size >= 0){ + n1 = sfeof(a1)?0:sgetc(a1); + n2 = sfeof(a2)?0:sgetc(a2); + n = n1 + n2 + carry; + if(n>=100){ + carry=1; + n -= 100; + } + else if(n<0){ + carry = -1; + n += 100; + } + else carry = 0; + sputc(p,n); + } + if(carry != 0)sputc(p,carry); + fsfile(p); + if(sfbeg(p) == 0){ + while(sfbeg(p) == 0 && (c = sbackc(p)) == 0); + if(c != 0)salterc(p,c); + truncate(p); + } + fsfile(p); + if(sfbeg(p) == 0 && sbackc(p) == -1){ + while((c = sbackc(p)) == 99){ + if(c == EOF)break; + } + sgetc(p); + salterc(p,-1); + truncate(p); + } + return(p); +} + +int +eqk(void){ + register struct blk *p,*q; + register int skp; + int skq; + + p = pop(); + EMPTYS; + q = pop(); + EMPTYSR(p); + skp = sunputc(p); + skq = sunputc(q); + if(skp == skq){ + arg1=p; + arg2=q; + savk = skp; + return(0); + } + else if(skp < skq){ + savk = skq; + p = add0(p,skq-skp); + } + else { + savk = skp; + q = add0(q,skp-skq); + } + arg1=p; + arg2=q; + return(0); +} + +struct blk * +removc(struct blk *p,int n) +{ + register struct blk *q,*r; + + rewind(p); + while(n>1){ + sgetc(p); + n -= 2; + } + q = salloc(2); + while(sfeof(p) == 0)sputc(q,sgetc(p)); + if(n == 1){ + r = dcdiv(q,tenptr); + release(q); + release(rem); + q = r; + } + release(p); + return(q); +} + +struct blk * +scalint(struct blk *p) +{ + register int n; + n = sunputc(p); + p = removc(p,n); + return(p); +} + +struct blk * +scale(struct blk *p,int n) +{ + register struct blk *q,*s,*t; + + t = add0(p,n); + q = salloc(1); + sputc(q,n); + s = dcexp(inbas,q); + release(q); + q = dcdiv(t,s); + release(t); + release(s); + release(rem); + sputc(q,n); + return(q); +} + +int +subt(void){ + arg1=pop(); + EMPTYS; + savk = sunputc(arg1); + chsign(arg1); + sputc(arg1,savk); + pushp(arg1); + if(eqk() != 0)return(1); + binop('+'); + return(0); +} + +int +command(void){ + int c; + static char *line; + static int linesize; + char *sl; + register void (*savint)(int); + register int pid,rpid; + int retcode; + + switch(c = readc()){ + case '<': + return(cond(NL)); + case '>': + return(cond(NG)); + case '=': + return(cond(NE)); + default: + if (line == 0) + line = srealloc(0, linesize = 10); + sl = line; + *sl++ = c; + while((c = readc()) != '\n') { + if (sl >= &line[linesize-2]) { + int diff = sl - line; + line = srealloc(line, linesize += 10); + sl = &line[diff]; + } + *sl++ = c; + } + *sl = 0; + if((pid = fork()) == 0){ + execl(SHELL,"sh","-c",line,NULL); + exit(0100); + } + savint = sigset(SIGINT, SIG_IGN); + while((rpid = wait(&retcode)) != pid && rpid != -1); + sigset(SIGINT,savint); + printf("!\n"); + return(0); + } +} + +int +cond(char c) +{ + register struct blk *p; + register int cc; + + if(subt() != 0)return(1); + p = pop(); + sunputc(p); + if(length(p) == 0){ + release(p); + if(c == '<' || c == '>' || c == NE){ + readc(); + return(0); + } + load(); + return(1); + } + else { + if(c == '='){ + release(p); + readc(); + return(0); + } + } + if(c == NE){ + release(p); + load(); + return(1); + } + fsfile(p); + cc = sbackc(p); + release(p); + if((cc<0 && (c == '<' || c == NG)) || + (cc >0) && (c == '>' || c == NL)){ + readc(); + return(0); + } + load(); + return(1); +} + +void +load(void){ + register int c; + register struct blk *p,*q; + struct blk *t,*s; + c = readc() & 0377; + sptr = stable[c]; + if(sptr != 0){ + p = sptr->val; + if(c >= ARRAYST){ + q = salloc(length(p)); + rewind(p); + while(sfeof(p) == 0){ + s = dcgetwd(p); + if(s == 0){putwd(q, (struct blk *)NULL);} + else{ + t = copy(s,length(s)); + putwd(q,t); + } + } + pushp(q); + } + else{ + q = copy(p,length(p)); + pushp(q); + } + } + else{ + q = salloc(1); + sputc(q,0); + pushp(q); + } + return; +} + +int +log_2(long n) +{ + register int i; + + if(n == 0)return(0); + i=31; + if(n<0)return(i); + while((n= n<<1) >0)i--; + return(--i); +} + +struct blk * +salloc(int size) +{ + register struct blk *hdr; + register char *ptr; + all++; + nbytes += size; + ptr = malloc((unsigned)(size?size:1)); + if(ptr == 0){ + garbage("salloc"); + if((ptr = malloc((unsigned)(size?size:1))) == 0) + ospace("salloc"); + } + if((hdr = hfree) == 0)hdr = morehd(); + hfree = (struct blk *)hdr->rd; + hdr->rd = hdr->wt = hdr->beg = ptr; + hdr->last = ptr+size; + return(hdr); +} + +struct blk * +morehd(void){ + register struct blk *h,*kk; + headmor++; + nbytes += HEADSZ; + hfree = h = (struct blk *)malloc(HEADSZ); + if(hfree == 0){ + garbage("morehd"); + if((hfree = h = (struct blk *)malloc(HEADSZ)) == 0) + ospace("headers"); + } + kk = h; + while(h<hfree+(HEADSZ/BLK))(h++)->rd = (char *)++kk; + (--h)->rd=0; + return(hfree); +} + +/* +sunputc(struct blk *hptr) +{ + hptr->wt--; + hptr->rd = hptr->wt; + return(*hptr->wt); +} +*/ + +struct blk * +copy(struct blk *hptr,int size) +{ + register struct blk *hdr; + register unsigned sz; + register char *ptr; + + all++; + nbytes += size; + sz = length(hptr); + ptr = nalloc(hptr->beg, (unsigned)size); + if(ptr == 0){ + garbage("copy"); + if((ptr = nalloc(hptr->beg, (unsigned)size)) == NULL){ + printf("copy size %d\n",size); + ospace("copy"); + } + } + if((hdr = hfree) == 0)hdr = morehd(); + hfree = (struct blk *)hdr->rd; + hdr->rd = hdr->beg = ptr; + hdr->last = ptr+size; + hdr->wt = ptr+sz; + ptr = hdr->wt; + while(ptr<hdr->last)*ptr++ = '\0'; + return(hdr); +} + +void +sdump(char *s1,struct blk *hptr) +{ + char *p; + printf("%s %lo rd %lo wt %lo beg %lo last %lo\n", s1, + (long)(intptr_t)hptr, + (long)(intptr_t)hptr->rd, + (long)(intptr_t)hptr->wt, + (long)(intptr_t)hptr->beg, + (long)(intptr_t)hptr->last); + p = hptr->beg; + while(p < hptr->wt)printf("%d ",*p++); + printf("\n"); +} + +void +seekc(struct blk *hptr,int n) +{ + register char *nn,*p; + + nn = hptr->beg+n; + if(nn > hptr->last){ + nbytes += nn - hptr->last; + /*free(hptr->beg);*/ + p = realloc(hptr->beg, (unsigned)n); + if(p == 0){ + hptr->beg = realloc(hptr->beg, (unsigned)(hptr->last-hptr->beg)); + garbage("seekc"); + if((p = realloc(hptr->beg, (unsigned)n)) == 0) + ospace("seekc"); + } + hptr->beg = p; + hptr->wt = hptr->last = hptr->rd = p+n; + return; + } + hptr->rd = nn; + if(nn>hptr->wt)hptr->wt = nn; + return; +} + +void +salterwd(struct wblk *hptr,struct blk *n) +{ + if(hptr->rdw == hptr->lastw)more((struct blk *)hptr); + *hptr->rdw++ = n; + if(hptr->rdw > hptr->wtw)hptr->wtw = hptr->rdw; + return; +} + +void +more(struct blk *hptr) +{ + register unsigned size; + register char *p; + + if((size=(hptr->last-hptr->beg)*2) == 0)size=1; + nbytes += size/2; + /*free(hptr->beg);*/ + p = realloc(hptr->beg, (unsigned)size); + if(p == 0){ + hptr->beg = realloc(hptr->beg, (unsigned)(hptr->last-hptr->beg)); + garbage("more"); + if((p = realloc(hptr->beg,size)) == 0) + ospace("more"); + } + hptr->rd = hptr->rd-hptr->beg+p; + hptr->wt = hptr->wt-hptr->beg+p; + hptr->beg = p; + hptr->last = p+size; + return; +} + +void +ospace(char *s) +{ + printf("out of space: %s\n",s); + printf("all %ld rel %ld headmor %ld\n",all,rel,headmor); + printf("nbytes %ld\n",nbytes); + sdump("stk",*stkptr); + abort(); +} + +void +garbage(char *s) +{ + int i; + struct blk *p, *q; + struct sym *tmps; + int ct; + +/* printf("got to garbage %s\n",s); */ + for(i=0;i<TBLSZ;i++){ + tmps = stable[i]; + if(tmps != 0){ + if(i < ARRAYST){ + do { + p = tmps->val; + if(((intptr_t)p->beg & 01) != 0){ + printf("string %o\n",i); + sdump("odd beg",p); + } + redef(p); + tmps = tmps->next; + } while(tmps != 0); + continue; + } + else { + do { + p = tmps->val; + rewind(p); + ct = 0; + while((q = dcgetwd(p)) != NULL){ + ct++; + if(q != 0){ + if(((intptr_t)q->beg & 01) != 0){ + printf("array %o elt %d odd\n",i-ARRAYST,ct); +printf("tmps %lo p %lo\n",(long)(intptr_t)tmps,(long)(intptr_t)p); + sdump("elt",q); + } + redef(q); + } + } + tmps = tmps->next; + } while(tmps != 0); + } + } + } +} + +void +redef(struct blk *p) +{ + register int offset; + register char *newp; + + if ((intptr_t)p->beg&01) { + printf("odd ptr %lo hdr %lo\n",(long)(intptr_t)p->beg, + (long)(intptr_t)p); + ospace("redef-bad"); + } + /*free(p->beg);*/ + newp = realloc(p->beg, (unsigned)(p->last-p->beg)); + if(newp == NULL)ospace("redef"); + offset = newp - p->beg; + p->beg = newp; + p->rd += offset; + p->wt += offset; + p->last += offset; +} + +void +release(register struct blk *p) +{ + rel++; + nbytes -= p->last - p->beg; + p->rd = (char *)hfree; + hfree = p; + free(p->beg); +} + +struct blk * +dcgetwd(struct blk *p) +{ + register struct wblk *wp; + + wp = (struct wblk *)p; + if (wp->rdw == wp->wtw) + return(NULL); + return(*wp->rdw++); +} + +void +putwd(struct blk *p, struct blk *c) +{ + register struct wblk *wp; + + wp = (struct wblk *)p; + if (wp->wtw == wp->lastw) + more(p); + *wp->wtw++ = c; +} + +struct blk * +lookwd(struct blk *p) +{ + register struct wblk *wp; + + wp = (struct wblk *)p; + if (wp->rdw == wp->wtw) + return(NULL); + return(*wp->rdw); +} + +char * +nalloc(register char *p,unsigned nbytes) +{ + register char *q, *r; + q = r = malloc(nbytes ? nbytes : 1); + if(q==0) + return(0); + while(nbytes--) + *q++ = *p++; + return(r); +} + +void * +srealloc(void *op, size_t size) +{ + void *np; + + if ((np = realloc(op, size)) == 0) { + write(2, "no memory\n", 10); + _exit(077); + } + return np; +} diff --git a/dc/dc.h b/dc/dc.h @@ -0,0 +1,203 @@ +/* from Unix 7th Edition /usr/src/cmd/dc/dc.h */ +/* + * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * Redistributions of source code and documentation must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed or owned by Caldera + * International, Inc. + * Neither the name of Caldera International, Inc. nor the names of + * other contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA + * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE + * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Sccsid @(#)dc.h 1.9 (gritter) 2/4/05> */ + +#include <stdlib.h> +#include <signal.h> + +#define FATAL 0 +#define NFATAL 1 +#define BLK sizeof(struct blk) +#define PTRSZ sizeof(int *) +#define HEADSZ 1024 +#define STKSZ 100 +#define RDSKSZ 100 +#define TBLSZ 256 +#define ARRAYST 0241 +#define NL 1 +#define NG 2 +#define NE 3 +#define length(p) ((p)->wt-(p)->beg) +#define rewind(p) (p)->rd=(p)->beg +#define create(p) (p)->rd = (p)->wt = (p)->beg +#define fsfile(p) (p)->rd = (p)->wt +#define truncate(p) (p)->wt = (p)->rd +#define sfeof(p) (((p)->rd>=(p)->wt)?1:0) +#define sfbeg(p) (((p)->rd==(p)->beg)?1:0) +#define sungetc(p,c) *(--(p)->rd)=c +#ifdef interdata +#define NEGBYTE 0200 +#define MASK (-1 & ~0377) +#define sgetc(p) ( ((p)->rd==(p)->wt) ? EOF :( ((*(p)->rd & NEGBYTE) != 0) ? ( *(p)->rd++ | MASK): *(p)->rd++ )) +#define slookc(p) ( ((p)->rd==(p)->wt) ? EOF :( ((*(p)->rd & NEGBYTE) != 0) ? (*(p)->rd | MASK) : *(p)->rd )) +#define sbackc(p) ( ((p)->rd==(p)->beg) ? EOF :( ((*(--(p)->rd) & NEGBYTE) != 0) ? (*(p)->rd | MASK): *(p)->rd )) +#endif +#ifndef interdata +#define sgetc(p) (((p)->rd==(p)->wt)?EOF:*(p)->rd++) +#define slookc(p) (((p)->rd==(p)->wt)?EOF:*(p)->rd) +#define sbackc(p) (((p)->rd==(p)->beg)?EOF:*(--(p)->rd)) +#endif +#define sputc(p,c) {if((p)->wt==(p)->last)more(p); *(p)->wt++ = c; } +#define salterc(p,c) {if((p)->rd==(p)->last)more(p); *(p)->rd++ = c; if((p)->rd>(p)->wt)(p)->wt=(p)->rd;} +#define sunputc(p) (*( (p)->rd = --(p)->wt)) +#define zero(p) for(pp=(p)->beg;pp<(p)->last;)*pp++='\0' +#define OUTC(x) {int _c = (x); if (_c) {printf("%c",_c); if(--count == 0){printf("\\\n"); count=ll;} } } +#define TEST2(b) { OUTC(b[0] & 0377); OUTC(b[1] & 0377); } +#define EMPTY if(stkerr != 0){printf("stack empty\n"); continue; } +#define EMPTYR(x) if(stkerr!=0){pushp(x);printf("stack empty\n");continue;} +#define EMPTYS if(stkerr != 0){printf("stack empty\n"); return(1);} +#define EMPTYSR(x) if(stkerr !=0){printf("stack empty\n");pushp(x);return(1);} +#define error(p) {printf(p); continue; } +#define errorrt(p) {printf(p); return(1); } +struct blk { + char *rd; + char *wt; + char *beg; + char *last; +}; +struct blk *hfree; +struct blk *arg1, *arg2; +int svargc; +char savk; +char **svargv; +int dbg; +int ifile; +FILE *curfile; +struct blk *scalptr, *basptr, *tenptr, *inbas; +struct blk *sqtemp, *chptr, *strptr, *divxyz; +struct blk *stack[STKSZ]; +struct blk **stkptr,**stkbeg; +struct blk **stkend; +int stkerr; +int lastchar; +struct blk *readstk[RDSKSZ]; +struct blk **readptr; +struct blk *rem; +int k; +struct blk *irem; +int skd,skr; +int neg; +struct sym { + struct sym *next; + struct blk *val; +} symlst[TBLSZ]; +struct sym *stable[TBLSZ]; +struct sym *sptr,*sfree; +struct wblk { + struct blk **rdw; + struct blk **wtw; + struct blk **begw; + struct blk **lastw; +}; +FILE *fsave; +long rel; +long nbytes; +long all; +long headmor; +long obase; +int fw,fw1,ll; +int (*outdit)(struct blk *, int, int); +int logo; +int log_10; +int count; +char *pp; +char *dummy; + +#define div(a, b) dcdiv(a, b) +#define sqrt(a) dcsqrt(a) +#define exp(a, b) dcexp(a, b) +#define getwd(a) dcgetwd(a) +extern void commnds(void); +extern struct blk *div(struct blk *, struct blk *); +extern int dscale(void); +extern struct blk *removr(struct blk *, int); +extern struct blk *sqrt(struct blk *); +extern struct blk *exp(struct blk *, struct blk *); +extern void init(int, char *[]); +extern void onintr(int); +extern void pushp(struct blk *); +extern struct blk *pop(void); +extern struct blk *readin(void); +extern struct blk *add0(struct blk *, int); +extern struct blk *mult(struct blk *, struct blk *); +extern void chsign(struct blk *); +extern int readc(void); +extern void unreadc(char); +extern void binop(char); +extern void print(struct blk *); +extern struct blk *getdec(struct blk *, int); +extern void tenot(struct blk *, int); +extern void oneot(struct blk *, int, char); +extern void hexot(struct blk *, int, int); +extern void bigot(struct blk *, int, int); +extern struct blk *add(struct blk *, struct blk *); +extern int eqk(void); +extern struct blk *removc(struct blk *, int); +extern struct blk *scalint(struct blk *); +extern struct blk *scale(struct blk *, int); +extern int subt(void); +extern int command(void); +extern int cond(char); +extern void load(void); +extern int log_2(long); +extern struct blk *salloc(int); +extern struct blk *morehd(void); +extern struct blk *copy(struct blk *, int); +extern void sdump(char *, struct blk *); +extern void seekc(struct blk *, int); +extern void salterwd(struct wblk *, struct blk *); +extern void more(struct blk *); +extern void ospace(char *); +extern void garbage(char *); +extern void redef(struct blk *); +extern void release(register struct blk *); +extern struct blk *getwd(struct blk *); +extern void putwd(struct blk *, struct blk *); +extern struct blk *lookwd(struct blk *); +extern char *nalloc(register char *, unsigned); +extern void *srealloc(void *, size_t); + +#if defined (__GLIBC__) && defined (_IO_getc_unlocked) +#undef getc +#define getc(f) _IO_getc_unlocked(f) +#endif + +#ifndef BC_BASE_MAX +#define BC_BASE_MAX 99 +#endif +#ifndef BC_DIM_MAX +#define BC_DIM_MAX 2048 +#endif diff --git a/dc/mkfile b/dc/mkfile @@ -0,0 +1,8 @@ +BIN = dc +OBJ = dc.o +LOCAL_CFLAGS = -DSHELL=\"$SHELL\" +INSTALL_BIN = dc +INSTALL_MAN1 = dc.1 +DEPS = libcommon + +<$mkbuild/mk.default diff --git a/dc/version.c b/dc/version.c @@ -0,0 +1,13 @@ +#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 +#define USED __attribute__ ((used)) +#elif defined __GNUC__ +#define USED __attribute__ ((unused)) +#else +#define USED +#endif +static const char sccsid[] USED = "@(#)dc.sl 2.12 (gritter) 12/25/06"; +/* SLIST */ +/* +dc.c: Sccsid @(#)dc.c 1.21 (gritter) 12/25/06> +dc.h: Sccsid @(#)dc.h 1.9 (gritter) 2/4/05> +*/ diff --git a/dd/dd.1 b/dd/dd.1 @@ -0,0 +1,293 @@ +.\" +.\" Sccsid @(#)dd.1 1.7 (gritter) 1/14/05 +.\" +.\" Parts taken from dd(1), Unix 7th edition: +.\" Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" Redistributions of source code and documentation must retain the +.\" above copyright notice, this list of conditions and the following +.\" disclaimer. +.\" Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed or owned by Caldera +.\" International, Inc. +.\" Neither the name of Caldera International, Inc. nor the names of +.\" other contributors may be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA +.\" INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE +.\" LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.TH DD 1 "1/14/05" "Heirloom Toolchest" "User Commands" +.SH NAME +dd \- convert and copy a file +.SH SYNOPSIS +.B dd +[option=value] ... +.SH DESCRIPTION +.I Dd +copies the specified input file +to the specified output with +possible conversions. +The standard input and output are used by default. +The input and output block size may be +specified to take advantage of raw physical I/O. +.PP +.br +.ns +.TP 15 +.I option +.I values +.br +.ns +.TP +if= +input file name; standard input is default +.br +.ns +.TP +of= +output file name; standard output is default +.br +.ns +.TP +.RI ibs= n +input block size +.I n +bytes (default 512) +.br +.ns +.TP +.RI obs= n +output block size (default 512) +.br +.ns +.TP +.RI bs= n +set both input and output block size, +superseding +.I ibs +and +.I obs; +also, if no conversion is specified, +it is particularly efficient since no copy need be done +.br +.ns +.TP +.RI cbs= n +conversion buffer size +.br +.ns +.TP +.RI skip= n +skip +.IR n "" +input records before starting copy +.br +.ns +.TP +.RI iseek= n +seek +.IR n "" +input records before starting copy +.br +.ns +.TP +.RI files= n +copy +.I n +files from (tape) input +.br +.ns +.TP +.RI seek= n +seek +.I n +records from beginning of output file before copying +.br +.ns +.TP +.RI oseek= n +same as seek +.br +.ns +.TP +count=\fIn\fR +copy only +.IR n "" +input records +.br +.ns +.TP +conv=ascii +.ds h \h'\w'conv='u' +convert EBCDIC to ASCII +.br +.ns +.IP \*hebcdic +convert ASCII to EBCDIC +.br +.ns +.IP \*hibm +slightly different map of ASCII to EBCDIC +.br +.ns +.IP \*hblock +convert newline-terminated input lines to blocks +.br +.ns +.IP \*hunblock +convert blocked input to lines +.br +.ns +.IP \*hlcase +map alphabetics to lower case +.br +.ns +.IP \*hucase +map alphabetics to upper case +.br +.ns +.IP \*hswab +swap every pair of bytes +.br +.ns +.IP \*hnoerror +do not stop processing on an error +.br +.ns +.IP \*hnotrunc +do not truncate the output file +.br +.ns +.IP \*hsync +pad every input record to +.I ibs +.br +.ns +.IP "\*h... , ..." +several comma-separated conversions +.PP +.fi +Where sizes are specified, +a number of bytes is expected. +A number may end with +.B "k, b" +or +.B w +to specify multiplication by +1024, 512, or 2 respectively; +a pair of numbers may be separated by +.B x +to indicate a product. +.PP +.I Cbs +is used only if +.IR ascii , +.IR unblock, +.IR ebcdic , +.IR ibm , +or +.IR block +conversion is specified. +In the first two cases, +.I cbs +bytes are placed into the conversion buffer, converted to +ASCII, and trailing blanks trimmed and new-line added +before sending the line to the output. +In the latter three cases, +ASCII characters (bytes) are read into the +conversion buffer, converted to EBCDIC, and blanks added +to make up an +output record of size +.IR cbs . +.PP +Two additional values for the `conv' +option, `conv=idirect' and `conv=odirect', +are available as extensions. +They enable direct i/o on input or output, respectively. +See the description of the `O_DIRECT' flag in +.IR open (2) +for more information. +`conv=odirect' must be used with care +as it requires padding for correct operation; +a write that is not a multiple of an acceptable buffer size will fail. +This is particularly of concern for the last block written. +Using `conv=odirect' thus usually requires `conv=sync' +and cannot be used if such padding destroys the file integrity. +.PP +After completion, +.I dd +reports the number of whole and partial input and output +blocks. +.SH "ENVIRONMENT VARIABLES" +.TP +.BR LANG ", " LC_ALL +See +.IR locale (7). +.TP +.B LC_CTYPE +Determines the mapping of bytes to characters +for `conv=lcase' and `conv=ucase'. +.SH EXAMPLES +To read an EBCDIC tape blocked ten 80-byte +EBCDIC card images per record into the ASCII file +.IR x : +.IP "" +dd if=/dev/rmt0 of=x ibs=800 cbs=80 conv=ascii,lcase +.PP +Note the use of raw magtape. +.I Dd +is especially suited to I/O on the raw +physical devices because it allows reading +and writing in arbitrary record sizes. +.PP +To skip over a file before copying from magnetic tape do +.IP "" +(dd of=/dev/null; dd of=x) </dev/rmt0 +.SH "SEE ALSO" +cp(1), +tr(1), +locale(7) +.SH DIAGNOSTICS +f+p records in(out): numbers of full and partial records read(written) +.SH NOTES +The ASCII/EBCDIC conversion tables are +taken +.\" This was valid for v7/BSD conversion tables. +.\"from the 256 character standard in +.\"the CACM Nov, 1968. +.\" *** +.\" This is what various AT&T sources and mem(3) of libast say for the +.\" current tables. The tables itselves are given in the POSIX.2 rationale. +from a proposed BTL standard April 16, 1979. +The `ibm' conversion, while less blessed as a standard, +corresponds better to certain IBM print train conventions. +There is no universal solution. +.PP +When reading from pipes, FIFOs, character devices (e.\|g. terminals), +or network sockets, +partial input records can occur at any time +even before the end of the data stream is reached. +For the `count' option, +these are handled exactly like full records. +Using +.I dd +to retrieve exactly +.IR count * ibs +bytes from such files does thus not generally work unless `ibs=1'. diff --git a/dd/dd.c b/dd/dd.c @@ -0,0 +1,1035 @@ +/* + * dd - convert and copy + * + * Gunnar Ritter, Freiburg i. Br., Germany, January 2003. + */ +/* + * Copyright (c) 2003 Gunnar Ritter + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute + * it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 +#define USED __attribute__ ((used)) +#elif defined __GNUC__ +#define USED __attribute__ ((unused)) +#else +#define USED +#endif +static const char sccsid[] USED = "@(#)dd.sl 1.30 (gritter) 1/22/06"; + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <malloc.h> +#include <errno.h> +#include <libgen.h> +#include <ctype.h> +#include <locale.h> +#include <signal.h> +#include "sigset.h" +#include <wchar.h> +#include <wctype.h> +#include <limits.h> + +#include <sys/ioctl.h> + +#if defined (__linux__) || defined (__sun) || defined (__FreeBSD__) || \ + defined (__hpux) || defined (_AIX) || defined (__NetBSD__) || \ + defined (__OpenBSD__) || defined (__DragonFly__) || defined (__APPLE__) +#include <sys/mtio.h> +#else /* SVR4.2MP */ +#include <sys/scsi.h> +#include <sys/st01.h> +#endif /* SVR4.2MP */ + +#include "atoll.h" +#include "memalign.h" +#include "mbtowi.h" + +/* + * For 'conv=ascii'. + */ +static const unsigned char c_ascii[] = { +0000,0001,0002,0003,0234,0011,0206,0177,0227,0215,0216,0013,0014,0015,0016,0017, +0020,0021,0022,0023,0235,0205,0010,0207,0030,0031,0222,0217,0034,0035,0036,0037, +0200,0201,0202,0203,0204,0012,0027,0033,0210,0211,0212,0213,0214,0005,0006,0007, +0220,0221,0026,0223,0224,0225,0226,0004,0230,0231,0232,0233,0024,0025,0236,0032, +0040,0240,0241,0242,0243,0244,0245,0246,0247,0250,0325,0056,0074,0050,0053,0174, +0046,0251,0252,0253,0254,0255,0256,0257,0260,0261,0041,0044,0052,0051,0073,0176, +0055,0057,0262,0263,0264,0265,0266,0267,0270,0271,0313,0054,0045,0137,0076,0077, +0272,0273,0274,0275,0276,0277,0300,0301,0302,0140,0072,0043,0100,0047,0075,0042, +0303,0141,0142,0143,0144,0145,0146,0147,0150,0151,0304,0305,0306,0307,0310,0311, +0312,0152,0153,0154,0155,0156,0157,0160,0161,0162,0136,0314,0315,0316,0317,0320, +0321,0345,0163,0164,0165,0166,0167,0170,0171,0172,0322,0323,0324,0133,0326,0327, +0330,0331,0332,0333,0334,0335,0336,0337,0340,0341,0342,0343,0344,0135,0346,0347, +0173,0101,0102,0103,0104,0105,0106,0107,0110,0111,0350,0351,0352,0353,0354,0355, +0175,0112,0113,0114,0115,0116,0117,0120,0121,0122,0356,0357,0360,0361,0362,0363, +0134,0237,0123,0124,0125,0126,0127,0130,0131,0132,0364,0365,0366,0367,0370,0371, +0060,0061,0062,0063,0064,0065,0066,0067,0070,0071,0372,0373,0374,0375,0376,0377 +}; + +/* + * For 'conv=ibm'. + */ +static const unsigned char c_ibm[] = { +0000,0001,0002,0003,0067,0055,0056,0057,0026,0005,0045,0013,0014,0015,0016,0017, +0020,0021,0022,0023,0074,0075,0062,0046,0030,0031,0077,0047,0034,0035,0036,0037, +0100,0132,0177,0173,0133,0154,0120,0175,0115,0135,0134,0116,0153,0140,0113,0141, +0360,0361,0362,0363,0364,0365,0366,0367,0370,0371,0172,0136,0114,0176,0156,0157, +0174,0301,0302,0303,0304,0305,0306,0307,0310,0311,0321,0322,0323,0324,0325,0326, +0327,0330,0331,0342,0343,0344,0345,0346,0347,0350,0351,0255,0340,0275,0137,0155, +0171,0201,0202,0203,0204,0205,0206,0207,0210,0211,0221,0222,0223,0224,0225,0226, +0227,0230,0231,0242,0243,0244,0245,0246,0247,0250,0251,0300,0117,0320,0241,0007, +0040,0041,0042,0043,0044,0025,0006,0027,0050,0051,0052,0053,0054,0011,0012,0033, +0060,0061,0032,0063,0064,0065,0066,0010,0070,0071,0072,0073,0004,0024,0076,0341, +0101,0102,0103,0104,0105,0106,0107,0110,0111,0121,0122,0123,0124,0125,0126,0127, +0130,0131,0142,0143,0144,0145,0146,0147,0150,0151,0160,0161,0162,0163,0164,0165, +0166,0167,0170,0200,0212,0213,0214,0215,0216,0217,0220,0232,0233,0234,0235,0236, +0237,0240,0252,0253,0254,0255,0256,0257,0260,0261,0262,0263,0264,0265,0266,0267, +0270,0271,0272,0273,0274,0275,0276,0277,0312,0313,0314,0315,0316,0317,0332,0333, +0334,0335,0336,0337,0352,0353,0354,0355,0356,0357,0372,0373,0374,0375,0376,0377 +}; + +/* + * For 'conv=ebcdic'. + */ +static const unsigned char c_ebcdic[] = { +0000,0001,0002,0003,0067,0055,0056,0057,0026,0005,0045,0013,0014,0015,0016,0017, +0020,0021,0022,0023,0074,0075,0062,0046,0030,0031,0077,0047,0034,0035,0036,0037, +0100,0132,0177,0173,0133,0154,0120,0175,0115,0135,0134,0116,0153,0140,0113,0141, +0360,0361,0362,0363,0364,0365,0366,0367,0370,0371,0172,0136,0114,0176,0156,0157, +0174,0301,0302,0303,0304,0305,0306,0307,0310,0311,0321,0322,0323,0324,0325,0326, +0327,0330,0331,0342,0343,0344,0345,0346,0347,0350,0351,0255,0340,0275,0232,0155, +0171,0201,0202,0203,0204,0205,0206,0207,0210,0211,0221,0222,0223,0224,0225,0226, +0227,0230,0231,0242,0243,0244,0245,0246,0247,0250,0251,0300,0117,0320,0137,0007, +0040,0041,0042,0043,0044,0025,0006,0027,0050,0051,0052,0053,0054,0011,0012,0033, +0060,0061,0032,0063,0064,0065,0066,0010,0070,0071,0072,0073,0004,0024,0076,0341, +0101,0102,0103,0104,0105,0106,0107,0110,0111,0121,0122,0123,0124,0125,0126,0127, +0130,0131,0142,0143,0144,0145,0146,0147,0150,0151,0160,0161,0162,0163,0164,0165, +0166,0167,0170,0200,0212,0213,0214,0215,0216,0217,0220,0152,0233,0234,0235,0236, +0237,0240,0252,0253,0254,0112,0256,0257,0260,0261,0262,0263,0264,0265,0266,0267, +0270,0271,0272,0273,0274,0241,0276,0277,0312,0313,0314,0315,0316,0317,0332,0333, +0334,0335,0336,0337,0352,0353,0354,0355,0356,0357,0372,0373,0374,0375,0376,0377 +}; + +static char *progname; /* argv[0] to main() */ + +typedef long long d_type; + +static char *iblok; /* input buffer */ +static char *oblok; /* output buffer */ +static char *cblok; /* conversion buffer */ + +static char mblok[MB_LEN_MAX+1]; /* tow{upper|lower} buffer */ +static char *mbp; /* points to remaining chars in mblok */ +static int mbrest; /* number of remaining chars in mblok */ + +static const char *iffile; /* input file name */ +static int iffd; /* input file descriptor */ +static const char *offile; /* output file name */ +static int offd; /* output file descriptor */ +static struct stat istat; /* stat of input */ +static struct stat ostat; /* stat of output */ +static d_type ibs = 512; /* input block size */ +static d_type obs = 512; /* output block size */ +static d_type bs; /* size for both buffers */ +static d_type oflow; /* remaining bytes in output buffer */ +static d_type cbs; /* conversion block size */ +static d_type cflow; /* remaining bytes in conv. buffer */ +static int ctrunc; /* truncate current data (conv=block) */ +static d_type skip; /* skip these blocks on input */ +static d_type count = -1; /* no more than count blocks of input */ +static int files = 1; /* read EOF this many times */ +static d_type iseek; /* seek these blocks on input */ +static d_type oseek; /* seek these blocks on output */ +static int mb_cur_max; /* MB_CUR_MAX acceleration */ + +static d_type iwhole; /* statistics */ +static d_type ipartial; +static d_type owhole; +static d_type opartial; +static d_type truncated; + +static enum charconv { + CHAR_NONE = 0, + CHAR_ASCII = 1, + CHAR_EBCDIC = 2, + CHAR_IBM = 3 +} chars = CHAR_NONE; + +static enum conversion { + CONV_NONE = 0, + CONV_BLOCK = 01, + CONV_UNBLOCK = 02, + CONV_LCASE = 04, + CONV_UCASE = 010, + CONV_SWAB = 020, + CONV_NOERROR = 040, + CONV_NOTRUNC = 0100, + CONV_IDIRECT = 0200, + CONV_ODIRECT = 0400, + CONV_DIRECT = 0600, + CONV_SYNC = 01000 +} convs = CONV_NONE; + +static struct { + const char *c_name; + enum conversion c_conv; + enum charconv c_char; +} convtab[] = { + { "ascii", CONV_UNBLOCK, CHAR_ASCII }, + { "ebcdic", CONV_BLOCK, CHAR_EBCDIC }, + { "ibm", CONV_BLOCK, CHAR_IBM }, + { "block", CONV_BLOCK, CHAR_NONE }, + { "unblock", CONV_UNBLOCK, CHAR_NONE }, + { "lcase", CONV_LCASE, CHAR_NONE }, + { "ucase", CONV_UCASE, CHAR_NONE }, + { "swab", CONV_SWAB, CHAR_NONE }, + { "noerror", CONV_NOERROR, CHAR_NONE }, + { "notrunc", CONV_NOTRUNC, CHAR_NONE }, +#ifdef O_DIRECT + { "idirect", CONV_IDIRECT, CHAR_NONE }, + { "odirect", CONV_ODIRECT, CHAR_NONE }, +#endif /* O_DIRECT */ + { "sync", CONV_SYNC, CHAR_NONE }, + { NULL, CONV_NONE, CHAR_NONE } +}; + +static void * +bmalloc(size_t nbytes) +{ + static long pagesize; + void *vp; + + if (pagesize == 0) + if ((pagesize = sysconf(_SC_PAGESIZE)) < 0) + pagesize = 4096; + if ((vp = memalign(pagesize, nbytes)) == NULL) { + fprintf(stderr, "%s: not enough memory\n", progname); + fprintf(stderr, "Please use a smaller buffer size\n"); + exit(077); + } + return vp; +} + +/************************** ARGUMENT SCANNING ***************************/ +static void +badarg(const char *arg) +{ + fprintf(stderr, "%s: bad arg: \"%s\"\n", progname, arg); + exit(2); +} + +static void +badnumeric(const char *arg) +{ + fprintf(stderr, "%s: bad numeric arg: \"%s\"\n", progname, arg); + exit(2); +} + +static void +nozeroblok(void) +{ + fprintf(stderr, "%s: buffer sizes cannot be zero\n", progname); + exit(2); +} + +/* + * Get the value of a numeric argument. + */ +static d_type +expr(const char *ap) +{ + d_type val; + char *x; + int c; + + if (*ap == '-' || *ap == '+') + badnumeric(ap); + val = strtoull(ap, &x, 10); + while ((c = *x++) != '\0') { + switch (c) { + case 'k': + val *= 1024; + break; + case 'b': + val *= 512; + break; + case 'w': + val *= 2; + break; + case 'x': + case '*': + return val * expr(x); + default: + badnumeric(ap); + } + } + return val; +} + +static void +setin(const char *ap) +{ + iffile = ap; +} + +static void +setof(const char *ap) +{ + offile = ap; +} + +static void +setibs(const char *ap) +{ + ibs = expr(ap); + if (ibs == 0) + nozeroblok(); +} + +static void +setobs(const char *ap) +{ + obs = expr(ap); + if (obs == 0) + nozeroblok(); +} + +static void +setbs(const char *ap) +{ + bs = expr(ap); +} + +static void +setcbs(const char *ap) +{ + cbs = expr(ap); +} + +static void +setskip(const char *ap) +{ + skip = expr(ap); +} + +static void +setcount(const char *ap) +{ + count = expr(ap); +} + +static void +setconv(const char *ap) +{ + const char *cp, *cq; + int i; + + for (;;) { + while (*ap == ',') + ap++; + if (*ap == '\0') + break; + for (i = 0; convtab[i].c_name; i++) { + for (cp = convtab[i].c_name, cq = ap; + *cp && (*cp == *cq); + cp++, cq++); + if (*cp == '\0' && (*cq == ',' || *cq == '\0')) { + convs |= convtab[i].c_conv; + if (convtab[i].c_char != CHAR_NONE) + chars = convtab[i].c_char; + ap = cq; + goto next; + } + } + badarg(ap); + next:; + } +} + +static void +setfiles(const char *ap) +{ + files = expr(ap); +} + +static void +setiseek(const char *ap) +{ + iseek = expr(ap); +} + +static void +setoseek(const char *ap) +{ + oseek = expr(ap); +} + +static struct { + const char *a_name; + void (*a_func)(const char *); +} argtab[] = { + { "if=", setin }, + { "of=", setof }, + { "ibs=", setibs }, + { "obs=", setobs }, + { "bs=", setbs }, + { "cbs=", setcbs }, + { "skip=", setskip }, + { "seek=", setoseek }, + { "count=", setcount }, + { "conv=", setconv }, + { "files=", setfiles }, + { "iseek=", setiseek }, + { "oseek=", setoseek }, + { NULL, NULL } +}; + +static const char * +thisarg(const char *sp, const char *ap) +{ + do { + if (*sp != *ap) + return NULL; + if (*sp == '=') + return &sp[1]; + } while (*sp++ && *ap++); + return NULL; +} + +/******************************* EXECUTION ********************************/ +static void +stats(void) +{ + fprintf(stderr, "%llu+%llu records in\n", + (unsigned long long)iwhole, + (unsigned long long)ipartial); + fprintf(stderr, "%llu+%llu records out\n", + (unsigned long long)owhole, + (unsigned long long)opartial); + if (truncated) { + fprintf(stderr, "%llu truncated record%s\n", + (unsigned long long)truncated, + truncated > 1 ? "s" : ""); + } +} + +static void charconv(char *data, size_t size); +static void bflush(void); +static void cflush(void); +static void uflush(void); + +static void +quit(int status) +{ + if (mbp) + charconv(NULL, 0); + cflush(); + uflush(); + bflush(); + stats(); + exit(status); +} + +static void +onint(int sig) +{ + stats(); + exit(sig | 0200); +} + +static int +ontape(void) +{ + static int yes = -1; + + if (yes == -1) { +#if defined (__linux__) || defined (__FreeBSD__) || defined (__hpux) || \ + defined (_AIX) || defined (__NetBSD__) || defined (__OpenBSD__) || \ + defined (__DragonFly__) || defined (__APPLE__) + struct mtget mg; + yes = (istat.st_mode&S_IFMT) == S_IFCHR && + ioctl(iffd, MTIOCGET, &mg) == 0; +#elif defined (__sun) + struct mtdrivetype_request mr; + struct mtdrivetype md; + mr.size = sizeof md; + mr.mtdtp = &md; + yes = (istat.st_mode&S_IFMT) == S_IFCHR && + ioctl(iffd, MTIOCGETDRIVETYPE, &mr) == 0; +#else /* SVR4.2MP */ + struct blklen bl; + yes = (istat.st_mode&S_IFMT) == S_IFCHR && + ioctl(iffd, T_RDBLKLEN, &bl) == 0; +#endif /* SVR4.2MP */ + } + return yes; +} + +static void +seekconv(d_type count) +{ + ssize_t sz; + off_t offs; + + if (lseek(offd, 0, SEEK_CUR) != (off_t)-1) { + do { + if ((offs = lseek(offd, obs, SEEK_CUR)) == (off_t)-1) { + err: fprintf(stderr, "%s: output seek error: %s\n", + progname, strerror(errno)); + exit(3); + } + } while (--count); + if ((convs & CONV_NOTRUNC) == 0 && + (ostat.st_mode&S_IFMT) == S_IFREG) + ftruncate(offd, offs); + return; + } + while (count) { + if ((sz = read(offd, oblok, obs)) == 0) + break; + if (sz < 0) + goto err; + count--; + } + if (count) { + memset(oblok, 0, obs); + do { + if ((sz = write(offd, oblok, obs)) < 0) + goto err; + } while (--count); + } +} + +static void +skipconv(int canseek, d_type count) +{ + ssize_t rd = 0; + + if (canseek && lseek(iffd, 0, SEEK_CUR) == (off_t)-1) + canseek = 0; + while (count--) { + if (canseek) { + if (lseek(iffd, ibs, SEEK_CUR) != (off_t)-1) + rd = ibs; + else if (errno == EINVAL) + rd = 0; + else { + fprintf(stderr, "%s: input seek error: %s\n", + progname, strerror(errno)); + exit(3); + } + } else { + if ((rd = read(iffd, iblok, ibs)) < 0) { + fprintf(stderr, + "%s: read error during skip: %s\n", + progname, strerror(errno)); + exit(3); + } + } + if (rd == 0 && files-- <= 1) { + fprintf(stderr, "%s: cannot skip past end-of-file\n", + progname); + exit(3); + } + } +} + +static void +prepare(void) +{ + int flags; + + if (bs) + ibs = obs = bs; + iblok = bmalloc(ibs); + if (!(bs && chars == CHAR_NONE && + (convs|CONV_SYNC|CONV_NOERROR|CONV_NOTRUNC|CONV_DIRECT) + == (CONV_SYNC|CONV_NOERROR|CONV_NOTRUNC|CONV_DIRECT))) + oblok = bmalloc(obs); + if (cbs > 0) { + if ((convs & (CONV_BLOCK|CONV_UNBLOCK)) == 0) { + fprintf(stderr, + "%s: cbs must be zero if no block conversion requested\n", + progname); + exit(2); + } + cblok = bmalloc(cbs + 1); + } else + convs &= ~(CONV_BLOCK|CONV_UNBLOCK); + if ((iffd = iffile ? open(iffile, O_RDONLY) : dup(0)) < 0) { + fprintf(stderr, "%s: cannot open %s: %s\n", progname, + iffile ? iffile : "", strerror(errno)); + exit(1); + } + fstat(iffd, &istat); +#ifdef O_DIRECT + if (convs & CONV_IDIRECT) { + int flags; + flags = fcntl(iffd, F_GETFL); + fcntl(iffd, F_SETFL, flags | O_DIRECT); + } +#endif /* O_DIRECT */ + if (skip) + skipconv(0, skip); + else if (iseek) + skipconv(1, iseek); + flags = O_RDWR | O_CREAT; + if ((convs & CONV_NOTRUNC) == 0 && oseek == 0) + flags |= O_TRUNC; + if ((offd = offile ? open(offile, flags, 0666) : dup(1)) < 0) { + fprintf(stderr, "%s: cannot %s %s: %s\n", + progname, + flags & O_TRUNC ? "create" : "open", + offile ? offile : "", strerror(errno)); + exit(1); + } + fstat(offd, &ostat); +#ifdef O_DIRECT + if (convs & CONV_ODIRECT) { + int flags; + flags = fcntl(offd, F_GETFL); + fcntl(offd, F_SETFL, flags | O_DIRECT); + } +#endif /* O_DIRECT */ + if (oseek) + seekconv(oseek); +} + +static void +swabconv(char *data, size_t size) +{ + char c; + + while (size > 1) { + c = data[0]; + data[0] = data[1]; + data[1] = c; + size -= 2; + data += 2; + } +} + +static void +ascconv(char *data, size_t size) +{ + while (size--) { + *data = c_ascii[*data & 0377]; + data++; + } +} + +static ssize_t +swrite(const char *data, size_t size) +{ + ssize_t wt; + + for (;;) { + if ((wt = write(offd, data, size)) <= 0) { + if (errno == EINTR) + continue; + fprintf(stderr, "%s: write error: %s\n", + progname, strerror(errno)); + oflow = 0; + offd = -1; + quit(1); + } + break; + } + return wt; +} + +/* + * Write without output buffering (if bs= was specified). + */ +static void +dwrite(const char *data, size_t size) +{ + ssize_t wrt; + + do { + wrt = swrite(data, size); + if (wrt == obs) + owhole++; + else + opartial++; + data += wrt; + size -= wrt; + } while (size > 0); +} + +/* + * Write to output buffer. On short write, remaining data is kept within + * the buffer and written next time again. Might a warning be useful in + * this case? + */ +static void +bwrite(const char *data, size_t size) +{ + ssize_t wrt; + size_t di; + + while (oflow + size > obs) { + di = obs - oflow; + size -= di; + if (oflow) { + memcpy(&oblok[oflow], data, di); + wrt = swrite(oblok, obs); + } else + wrt = swrite(data, obs); + if (wrt != obs) { + memcpy(oblok, &(oflow ? oblok : data)[wrt], obs - wrt); + opartial++; + } else + owhole++; + oflow = obs - wrt; + data += di; + } + if (size == obs) { + if ((wrt = swrite(data, obs)) == obs) + owhole++; + else + opartial++; + size -= wrt; + data += wrt; + } + if (size) { + memcpy(&oblok[oflow], data, size); + oflow += size; + } +} + +static void +bflush(void) +{ + ssize_t wrt; + + if (offd >= 0) { + while (oflow) { + if ((wrt = swrite(oblok, oflow)) != oflow) + memcpy(oblok, &oblok[wrt], obs - wrt); + oflow -= wrt; + opartial++; + } + if (close(offd) < 0) { + fprintf(stderr, "%s: write error: %s\n", + progname, strerror(errno)); + offd = -1; + quit(1); + } + offd = -1; + } +} + +/* + * Handle conversions to EBCDIC. + */ +static void +ewrite(char *data, size_t size) +{ + char *dt = data; + size_t sz = size; + if (chars == CHAR_EBCDIC) { + while (sz--) { + *dt = c_ebcdic[*dt & 0377]; + dt++; + } + } else if (chars == CHAR_IBM) { + while (sz--) { + *dt = c_ibm[*dt & 0377]; + dt++; + } + } + bwrite(data, size); +} + +/* + * Handle 'conv=block'. + */ +static void +cflush(void) +{ + if (convs & CONV_BLOCK && cflow) { + while (cflow < cbs) + cblok[cflow++] = ' '; + ewrite(cblok, cbs); + cflow = 0; + } +} + +static void +cwrite(const char *data, size_t size) +{ + while (size) { + if (ctrunc == 0) { + cblok[cflow] = *data++; + if (cblok[cflow] == '\n') { + if (cflow == 0) + cblok[cflow++] = ' '; + cflush(); + } else if (++cflow == cbs) { + cflush(); + ctrunc = 1; + } + } else { + if (*data++ == '\n') + ctrunc = 0; + else if (ctrunc == 1) { + truncated++; + ctrunc = 2; + } + } + size--; + } +} + +/* + * Handle 'conv=unblock'. + */ +static void +uflush(void) +{ + char *cp; + + if (cflow) { + for (cp = &cblok[cflow-1]; cp >= cblok && *cp == ' '; cp--); + cp[1] = '\n'; + bwrite(cblok, cp - cblok + 2); + cflow = 0; + } +} + +static void +uwrite(const char *data, size_t size) +{ + while (size) { + while (cflow < cbs) { + cblok[cflow++] = *data++; + if (--size == 0) + return; + } + uflush(); + } +} + +static void +blokconv(char *data, size_t size) +{ + switch (chars) { + case CHAR_EBCDIC: + case CHAR_IBM: + if ((convs & (CONV_BLOCK|CONV_UNBLOCK)) == 0) { + ewrite(data, size); + break; + } + /*FALLTHRU*/ + default: + if (convs & CONV_BLOCK) + cwrite(data, size); + else if (convs & CONV_UNBLOCK) + uwrite(data, size); + else + bwrite(data, size); + break; + } +} + +static void +charconv(char *data, size_t size) +{ + if (convs & (CONV_LCASE|CONV_UCASE)) { + if (mb_cur_max > 1) { + /* + * Multibyte case conversion is somewhat ugly + * with dd as there is no guarantee that a + * character fits in an input block. We need + * another intermediate therefore to store + * incomplete multibyte sequences. + */ + int i, n, len; + wint_t wc; + int flush = size == 0; + + while (size > 0 || (flush && mbrest)) { + i = 0; + if (mbrest && mbp && mbp > mblok) { + do + mblok[i] = mbp[i]; + while (i++, --mbrest); + } else if (mbp == mblok) { + i = mbrest; + mbrest = 0; + } + if (i == 0 && size) { + mblok[i++] = *data++; + size--; + } + if (mblok[0] & 0200) { + while (i < mb_cur_max && size) { + mblok[i++] = *data++; + size--; + } + if (!flush && i < mb_cur_max) { + mbp = mblok; + mbrest = i; + return; + } + if ((n = mbtowi(&wc, mblok, i)) < 0) { + len = 1; + wc = WEOF; + } else if (n == 0) + len = 1; + else + len = n; + } else { + wc = mblok[0]; + len = n = 1; + } + if (i > 0) { + mbrest = i - len; + mbp = &mblok[len]; + } else { + mbrest = 0; + mbp = NULL; + } + if (wc != WEOF) { + char new[MB_LEN_MAX + 1]; + + if (convs & CONV_LCASE) + wc = wc & ~(wchar_t)0177 ? + towlower(wc) : + tolower(wc); + if (convs & CONV_UCASE) + wc = wc & ~(wchar_t)0177 ? + towupper(wc) : + toupper(wc); + if ((n = wctomb(new, wc)) > 0) + blokconv(new, n); + else + goto inv; + } else + inv: blokconv(mblok, len); + } + return; + } else { + char *dp = data; + size_t sz = size; + + while (sz--) { + if (convs & CONV_LCASE) + *dp = tolower(*dp & 0377); + if (convs & CONV_UCASE) + *dp = toupper(*dp & 0377); + dp++; + } + } + } + blokconv(data, size); +} + +static void +dd(void) +{ + ssize_t rd; + + while (count == -1 || count > 0) { + if ((rd = read(iffd, iblok, ibs)) < ibs) { + if (rd < 0) { + fprintf(stderr, "%s: read error: %s\n", + progname, strerror(errno)); + if (convs & CONV_NOERROR) { + stats(); + if (!ontape()) + lseek(iffd, ibs, SEEK_CUR); + if (convs & CONV_SYNC) + rd = 0; + else + continue; + } else + quit(1); + } else if (rd == 0) { + if (files-- <= 1) + break; + continue; + } else if (rd > 0) + ipartial++; + if (convs & CONV_SYNC) { + int c; + + c = convs&(CONV_BLOCK|CONV_UNBLOCK) ? ' ' : 0; + memset(&iblok[rd], c, ibs - rd); + rd = ibs; + } + } else + iwhole++; + if (count > 0) + count--; + if (bs && chars == CHAR_NONE && + (convs|CONV_SYNC|CONV_NOERROR|CONV_NOTRUNC|CONV_DIRECT) + == (CONV_SYNC|CONV_NOERROR|CONV_NOTRUNC|CONV_DIRECT)) + dwrite(iblok, rd); + else { + if (convs & CONV_SWAB) + swabconv(iblok, rd); + if (chars == CHAR_ASCII) + ascconv(iblok, rd); + charconv(iblok, rd); + } + } +} + +int +main(int argc, char **argv) +{ + const char *cp; + int o, i; + + progname = basename(argv[0]); + setlocale(LC_CTYPE, ""); + mb_cur_max = MB_CUR_MAX; + if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '-' && + argv[1][2] == '\0') + o = 2; + else + o = 1; + while (o < argc) { + for (i = 0; argtab[i].a_name; i++) { + if ((cp = thisarg(argv[o], argtab[i].a_name)) != 0) { + argtab[i].a_func(cp); + break; + } + } + if (argtab[i].a_name == NULL) + badarg(argv[o]); + o++; + } + if ((sigset(SIGINT, SIG_IGN)) != SIG_IGN) + sigset(SIGINT, onint); + prepare(); + dd(); + quit(0); + /*NOTREACHED*/ + return 0; +} diff --git a/dd/mkfile b/dd/mkfile @@ -0,0 +1,7 @@ +BIN = dd +OBJ = dd.o +INSTALL_BIN = dd +INSTALL_MAN1 = dd.1 +DEPS = libcommon + +<$mkbuild/mk.default diff --git a/diff/diff.1 b/diff/diff.1 @@ -0,0 +1,493 @@ +.\" +.\" Copyright (c) 1980 Regents of the University of California. +.\" All rights reserved. The Berkeley software License Agreement +.\" specifies the terms and conditions for redistribution. +.\" +.\" from 4.3BSD diff.1 6.4 (Berkeley) 5/19/86 +.\" +.\" This code contains changes by +.\" Gunnar Ritter, Freiburg i. Br., Germany, March 2003. All rights reserved. +.\" +.\" Conditions 1, 2, and 4 and the no-warranty notice below apply +.\" to these changes. +.\" +.\" +.\" Copyright (c) 1980, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowedgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" +.\" Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" Redistributions of source code and documentation must retain the +.\" above copyright notice, this list of conditions and the following +.\" disclaimer. +.\" Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed or owned by Caldera +.\" International, Inc. +.\" Neither the name of Caldera International, Inc. nor the names of +.\" other contributors may be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA +.\" INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE +.\" LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.TH DIFF 1 "6/28/05" "Heirloom Toolchest" "User Commands" +.SH NAME +diff \- differential file comparator +.SH SYNOPSIS +.HP +.nh +.ad l +\fBdiff\fR +[\fB\-abBiptw\fR] +[\fB\-cefhnu\fR] +[\fB\-C\ \fInumber\fR] +[\fB\-U\ \fInumber\fR] +\fIfile1\fR \fIfile2\fR +.HP +.nh +.ad l +\fBdiff\fR +[\fB\-abBiptw\fR] +[\fB\-D\ \fIstring\fR] +\fIfile1\fR \fIfile2\fR +.HP +.nh +.ad l +\fBdiff\fR +[\fB\-abBiNptw12\fR] +[\fB\-cefhnu\fR] +[\fB\-C\ \fInumber\fR] +[\fB\-U\ \fInumber\fR] +[\fB\-lrs\fR] +[\fB\-S\ \fIname\fR] +[\fB\-x\ \fIpattern\fR] +[\fB\-X\ \fIname\fR] +\fIdirectory1\fR \fIdirectory2\fR +.br +.hy 1 +.SH DESCRIPTION +.I Diff +tells what lines must be changed in two files to bring them +into agreement. +If +.I file1 +.RI ( file2 ) +is `\-', the standard input is used. +If +.I file1 +.RI ( file2 ) +is a directory, then a file in that directory +whose file-name is the same as the file-name of +.I file2 +.RI ( file1 ) +is used. +The normal output contains lines of these forms: +.IP "" 5 +.I n1 +a +.I n3,n4 +.br +.I n1,n2 +d +.I n3 +.br +.I n1,n2 +c +.I n3,n4 +.PP +These lines resemble +.I ed +commands to convert +.I file1 +into +.IR file2 . +The numbers after the letters pertain to +.IR file2 . +In fact, by exchanging `a' for `d' and reading backward +one may ascertain equally how to convert +.I file2 +into +.IR file1 . +As in +.I ed, +identical pairs where +.I n1 += +.I n2 +or +.I n3 += +.I n4 +are abbreviated as a single number. +.PP +Following each of these lines come all the lines that are +affected in the first file flagged by `<', +then all the lines that are affected in the second file +flagged by `>'. +.TP 10 +.B \-a +causes a list of differences to be output +for all files, +even for those found to have binary content. +This option is an extension. +.TP 10 +.B \-b +causes trailing whitespace characters +to be ignored, and other +strings of whitespace to compare equal. +.TP 10 +.B \-i +ignores the case of letters. E.g., ``A'' will compare equal to ``a''. +.TP 10 +.B \-p +causes the name of the surrounding C function, +or, more exactly, +of the first previous unchanged line +beginning with a letter, the dollar sign, or the underscore, +to be output with each set of changes. +Implies +.I \-c +unless +.I \-u +is also present. +This option is an extension. +.TP 10 +.B \-t +will expand tabs in output lines. Normal, +.B \-c +or +.B \-u +output adds character(s) to the front of each line which may screw up +the indentation of the original source lines and make the output listing +difficult to interpret. This option will preserve the original source's +indentation. +.TP 10 +.B \-w +is similar to +.B \-b +but causes whitespace characters +to be totally ignored. +E.g., ``if\ (\ a\ ==\ b\ )'' will compare equal to ``if(a==b)''. +.TP 10 +.B \-B +causes changes that consist entirely of empty lines added or deleted +to be ignored. +This option is an extension. +.PP +The following options are mutually exclusive: +.TP 10 +.B \-c +produces a diff with three lines of context. +With +.B \-c +the output format is modified slightly: +the output beginning with identification of the files involved and +their creation dates and then each change is separated +by a line with a dozen *'s. +The lines removed from +.I file1 +are marked with `\(mi '; those added to +.I file2 +are marked `+ '. Lines which are changed from one +file to the other are marked in both files with with `! '. +.\".sp +.\"Changes which lie within <context> lines of each other are grouped +.\"together on output. (This is a change from the previous ``diff -c'' +.\"but the resulting output is usually much easier to interpret.) +.TP 10 +\fB\-C\ \fInumber\fR +Same as +.B \-c +but uses +.I number +of lines of context. +.TP 10 +\fB\-D\ \fIstring\fR +causes +.I diff +to create a merged version of +.I file1 +and +.I file2 +on the standard output, with C preprocessor controls included so that +a compilation of the result without defining \fIstring\fR is equivalent +to compiling +.I file1, +while defining +.I string +will yield +.I file2. +.TP 10 +.B \-e +produces a script of +.I "a, c" +and +.I d +commands for the editor +.I ed, +which will recreate +.I file2 +from +.IR file1 . +In connection with +.BR \-e , +the following shell program may help maintain +multiple versions of a file. +Only an ancestral file ($1) and a chain of +version-to-version +.I ed +scripts ($2,$3,...) made by +.I diff +need be on hand. +A `latest version' appears on +the standard output. +.IP +\ \ \ \ \ \ \ \ (shift; cat $*; echo \'1,$p\') \(bv ed \- $1 +.IP +Extra commands are added to the output when comparing directories with +.B \-e, +so that the result is a +.IR sh (1) +script for converting text files which are common to the two directories +from their state in +.I dir1 +to their state in +.I dir2. +.TP 10 +.B \-f +produces a script similar to that of +.B \-e, +not useful with +.I ed, +and in the opposite order. +.TP 10 +.B \-h +does a fast, half-hearted job. +It works only when changed stretches are short +and well separated, +but does work on files of unlimited length. +.TP 10 +.B \-n +produces a script similar to that of +.B \-e, +but in the opposite order and with a count of changed lines on each +insert or delete command. +.\"This is the form used by +.\".IR rcsdiff (1). +.TP 10 +.B \-u +produces a unified diff with three lines of context. +The output begins with identification of the files involved +and their creation dates, +followed by the changes +separated by `@@ \-range +range @@'. +Lines removed from +.I file1 +are marked with `\(mi', +those added to +.I file2 +are marked `+'. +This option is an extension. +.TP 10 +\fB\-U\ \fInumber\fR +Same as +.B \-u +but uses +.I number +of lines of context. +This option is an extension. +.PP +If both arguments are directories, +.I diff +sorts the contents of the directories by name, and then runs the +regular file +.I diff +algorithm on text files which are different. +Binary files which differ, +common subdirectories, and files which appear in only one directory +are listed. +.PP +Options when comparing directories are: +.TP 10 +.B \-l +long output format; each text file +.I diff +is piped through +.IR pr (1) +to paginate it, +other differences are remembered and summarized +after all text file differences are reported. +.TP 10 +.B \-N +causes the text of files +that exist in one directory only +to be output +as if compared to an empty file modified at 1/1/70. +This option is an extension. +.TP 10 +.B \-1 +is similar to +.IR \-N , +but causes just the text of files that exist in +.I directory1 +only to be output. +Files that exist only in +.I directory2 +are listed. +This option is an extension. +.TP 10 +.B \-2 +is similar to +.IR \-N , +but causes just the text of files that exist in +.I directory2 +only to be output. +Files that exist only in +.I directory1 +are listed. +This option is an extension. +.TP 10 +.B \-r +causes application of +.I diff +recursively to common subdirectories encountered. +.TP 10 +.B \-s +causes +.I diff +to report files which are the same, which are otherwise not mentioned. +.TP 10 +.BI \-S " name" +starts a directory +.I diff +in the middle beginning with file +.I name. +.TP 10 +.BI \-x " pattern" +excludes all file names that match +.I pattern +(as described in +.IR glob (7)) +from comparison. +If +.I pattern +matches a directory, +files below that directory are also excluded. +This option is an extension. +.TP 10 +.BI \-X " name" +excludes all file names contained in +.IR name . +This option is an extension. +.SH "ENVIRONMENT VARIABLES" +.TP +.BR LANG ", " LC_ALL +See +.IR locale(7). +.TP +.B LC_CTYPE +Sets the mapping of bytes to characters, +character case translation +and the set of whitespace characters. +.TP +.B SYSV3 +If this variable is set, +invalid options are ignored instead of being rejected, +and the text of some diagnostic messages is changed. +.SH FILES +.ta \w'/usr/5lib/diffh 'u +/tmp/d????? +.br +/usr/5lib/diffh for \fB\-h\fR +.br +diff for directory diffs +.br +pr +.SH "SEE ALSO" +bdiff(1), +cmp(1), +cc(1), +comm(1), +ed(1), +diff3(1), +patch(1), +locale(7) +.SH DIAGNOSTICS +Exit status is 0 for no differences, 1 for some, 2 for trouble. +.SH NOTES +Editing scripts produced under the +.BR \-e " or" +.BR \-f " option are naive about" +creating lines consisting of a single `\fB.\fR'. +.PP +When comparing directories with the +\fB\-b, \-w\fP, or \fB\-i\fP +options specified, +.I diff +first compares the files ala +.I cmp, +and then decides to run the +.I diff +algorithm if they are not equal. +This may cause a small amount of spurious output if the files +then turn out to be identical because the only differences are +insignificant blank string or case differences. +.PP +When +.I diff +output is used with +.IR ed (1) +or +.IR patch (1) +for file synchronization, +it is recommended that it is run in the +.I C +or another single-byte LC_CTYPE locale +since character-to-byte conversion +might otherwise hide some changes. diff --git a/diff/diff.c b/diff/diff.c @@ -0,0 +1,473 @@ +/* + * This code contains changes by + * Gunnar Ritter, Freiburg i. Br., Germany, March 2003. All rights reserved. + * + * Conditions 1, 2, and 4 and the no-warranty notice below apply + * to these changes. + * + * + * Copyright (c) 1991 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * Redistributions of source code and documentation must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed or owned by Caldera + * International, Inc. + * Neither the name of Caldera International, Inc. nor the names of + * other contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA + * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE + * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Sccsid @(#)diff.c 1.24 (gritter) 3/27/05> */ +/* from 4.3BSD diff.c 4.6 4/3/86 */ + +#include "diff.h" +#include <unistd.h> +#include <locale.h> +#include <iblok.h> +/* + * diff - driver and subroutines + */ + +const char diff[] = "diff"; +const char diffh[] = DIFFH; +const char pr[] = "pr"; +const char *progname; +const char *argv0; + +static void usage(void); +static void xadd(const char *); +static void Xadd(const char *); + +int +main(int argc, char **argv) +{ + int i, invalid = 0; + + progname = basename(argv[0]); + setlocale(LC_CTYPE, ""); + mb_cur_max = MB_CUR_MAX; + if (getenv("SYSV3") != NULL) + sysv3 = 1; + ifdef1 = "FILE1"; ifdef2 = "FILE2"; + status = 2; + argv0 = argv[0]; + diffargv = argv; + while ((i = getopt(argc, argv, ":D:efnbBwitcC:uU:hS:rslNx:a12pX:")) + != EOF) { + switch (i) { +#ifdef notdef + case 'I': + opt = D_IFDEF; + wantelses = 0; + break; + case 'E': + opt = D_IFDEF; + wantelses = 1; + break; + case '1': + opt = D_IFDEF; + ifdef1 = optarg; + break; +#endif + case 'D': + /* -Dfoo = -E -1 -2foo */ + wantelses = 1; + ifdef1 = ""; + /* fall through */ +#ifdef notdef + case '2': +#endif + opt = D_IFDEF; + ifdef2 = optarg; + break; + case 'e': + opt = D_EDIT; + break; + case 'f': + opt = D_REVERSE; + break; + case 'n': + opt = D_NREVERSE; + break; + case 'b': + bflag = 1; + break; + case 'B': + Bflag = 1; + break; + case 'w': + wflag = 1; + break; + case 'i': + iflag = 1; + break; + case 't': + tflag = 1; + break; + case 'c': + opt = D_CONTEXT; + context = 3; + break; + case 'C': { + char *x; + + opt = D_CONTEXT; + context = strtol(optarg, &x, 10); + if (*x != '\0' || *optarg == '+' || *optarg == '-') { + fprintf(stderr, "%s: use -C num\n", progname); + done(); + } + break; + } + case 'u': + opt = D_UNIFIED; + context = 3; + break; + case 'U': { + char *x; + + opt = D_UNIFIED; + context = strtol(optarg, &x, 10); + if (*x != '\0' || *optarg == '+' || *optarg == '-') { + fprintf(stderr, "%s: use -U num\n", progname); + done(); + } + break; + } + case 'h': + hflag++; + break; + case 'S': + start = optarg; + break; + case 'r': + rflag++; + break; + case 's': + sflag++; + break; + case 'l': + lflag++; + break; + case 'N': + Nflag |= 3; + break; + case '1': + Nflag |= 1; + break; + case '2': + Nflag |= 2; + break; + case 'x': + xadd(optarg); + break; + case 'a': + aflag++; + break; + case 'p': + pflag++; + break; + case 'X': + Xadd(optarg); + break; + default: + if (invalid == 0 && !sysv3) + invalid = optopt; + } + } + argv += optind, argc -= optind; + if (argc != 2) { + fprintf(stderr, sysv3 ? "%s: arg count\n" : + "%s: two filename arguments required\n", + progname); + done(); + } + file1 = argv[0]; + file2 = argv[1]; + if (invalid) { + fprintf(stderr, "%s: invalid option -%c\n", progname, invalid); + usage(); + } + if (pflag) { + if (opt == D_UNIFIED || opt == D_CONTEXT) + /*EMPTY*/; + else if (opt == 0) { + opt = D_CONTEXT; + context = 3; + } else { + fprintf(stderr, + "%s: -p doesn't support -e, -f, -n, or -I\n", + progname); + done(); + } + } + if (hflag && opt) { + fprintf(stderr, + "%s: -h doesn't support -e, -f, -n, -c, -u, or -I\n", + progname); + done(); + } + diffany(argv); + /*NOTREACHED*/ + return 0; +} + +void +diffany(char **argv) +{ + if (!strcmp(file1, "-")) + stb1.st_mode = S_IFREG; + else if (stat(file1, &stb1) < 0) { + if (sysv3) + stb1.st_mode = S_IFREG; + else { + fprintf(stderr, "%s: %s: %s\n", progname, file1, + strerror(errno)); + done(); + } + } + if (!strcmp(file2, "-")) + stb2.st_mode = S_IFREG; + else if (stat(file2, &stb2) < 0) { + if (sysv3) + stb2.st_mode = S_IFREG; + else { + fprintf(stderr, "%s: %s: %s\n", progname, file2, + strerror(errno)); + done(); + } + } + if ((stb1.st_mode & S_IFMT) == S_IFDIR && + (stb2.st_mode & S_IFMT) == S_IFDIR) { + diffdir(argv); + } else + diffreg(); + done(); +} + +static void +usage(void) +{ + fprintf(stderr, "\ +usage: %s [ -bcefhilnrstw -C num -D string -S name ] file1 file2\n", + progname); + done(); +} + +int +min(int a,int b) +{ + + return (a < b ? a : b); +} + +int +max(int a,int b) +{ + + return (a > b ? a : b); +} + +void +done(void) +{ + if (tempfile1) { + unlink(tempfile1); + tempfile1 = NULL; + } + if (tempfile2) { + unlink(tempfile2); + tempfile2 = NULL; + } + if (recdepth == 0) + exit(status); + else + longjmp(recenv, 1); +} + +static void noroom(void); + +void * +dalloc(size_t n) +{ + struct stackblk *sp; + + if ((sp = malloc(n + sizeof *sp)) != NULL) { + sp->s_prev = NULL; + sp->s_next = curstack; + if (curstack) + curstack->s_prev = sp; + curstack = sp; + return (char *)sp + sizeof *sp; + } else + return NULL; +} + +void * +talloc(size_t n) +{ + register void *p; + + if ((p = dalloc(n)) == NULL) + noroom(); + return p; +} + +void * +ralloc(void *p,size_t n) +{ + struct stackblk *sp, *sq; + + if (p == NULL) + return talloc(n); + sp = (struct stackblk *)((char *)p - sizeof *sp); + if ((sq = realloc(sp, n + sizeof *sp)) == NULL) + noroom(); + if (sq->s_prev) + sq->s_prev->s_next = sq; + if (sq->s_next) + sq->s_next->s_prev = sq; + if (curstack == sp) + curstack = sq; + return (char *)sq + sizeof *sq; +} + +void +tfree(void *p) +{ + struct stackblk *sp; + + if (p == NULL) + return; + sp = (struct stackblk *)((char *)p - sizeof *sp); + if (sp->s_prev) + sp->s_prev->s_next = sp->s_next; + if (sp->s_next) + sp->s_next->s_prev = sp->s_prev; + if (sp == curstack) + curstack = sp->s_next; + free(sp); +} + +void +purgestack(void) +{ + struct stackblk *sp = curstack, *sq = NULL; + + do { + free(sq); + sq = sp; + if (sp) + sp = sp->s_next; + } while (sq); +} + +static void +noroom(void) +{ + oomsg(": files too big, try -h\n"); + status = 2; + done(); +} + +static void +xadd(const char *cp) +{ + struct xclusion *xp; + + xp = talloc(sizeof *xp); + xp->x_pat = cp; + xp->x_nxt = xflag; + xflag = xp; +} + +static void +Xadd(const char *name) +{ + struct iblok *ip; + char *line = NULL; + size_t size = 0, len; + + if (name[0] == '-' && name[1] == '\0') + ip = ib_alloc(0, 0); + else + ip = ib_open(name, 0); + if (ip == NULL) { + fprintf(stderr, "%s: -X %s: %s\n", progname, name, + strerror(errno)); + done(); + } + while ((len = ib_getlin(ip, &line, &size, realloc)) != 0) { + if (line[len-1] == '\n') + line[--len] = '\0'; + xadd(line); + line = NULL; + size = 0; + } + free(line); + if (ip->ib_fd) + ib_close(ip); + else + ib_free(ip); +} + +void +oomsg(const char *s) +{ + write(2, progname, strlen(progname)); + write(2, s, strlen(s)); +} diff --git a/diff/diff.h b/diff/diff.h @@ -0,0 +1,211 @@ +/* + * This code contains changes by + * Gunnar Ritter, Freiburg i. Br., Germany, March 2003. All rights reserved. + * + * Conditions 1, 2, and 4 and the no-warranty notice below apply + * to these changes. + * + * + * Copyright (c) 1991 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * Redistributions of source code and documentation must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed or owned by Caldera + * International, Inc. + * Neither the name of Caldera International, Inc. nor the names of + * other contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA + * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE + * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Sccsid @(#)diff.h 1.15 (gritter) 3/26/05> */ +/* from 4.3BSD diff.h 4.7 85/08/16 */ + +/* + * diff - common declarations + */ + +#include <stdio.h> +#include <ctype.h> +#include <sys/param.h> +#include <sys/stat.h> +#include <dirent.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#include <libgen.h> +#include <errno.h> +#include <setjmp.h> + +#if defined (__GLIBC__) +#if defined (_IO_getc_unlocked) +#undef getc +#define getc(f) _IO_getc_unlocked(f) +#endif +#if defined (_IO_putc_unlocked) +#undef putc +#define putc(c, f) _IO_putc_unlocked(c, f) +#undef putchar +#define putchar(c) _IO_putc_unlocked(c, stdout) +#endif +#endif + +/* + * Output format options + */ +int opt; + +#define D_NORMAL 0 /* Normal output */ +#define D_EDIT -1 /* Editor script out */ +#define D_REVERSE 1 /* Reverse editor script */ +#define D_CONTEXT 2 /* Diff with context */ +#define D_IFDEF 3 /* Diff with merged #ifdef's */ +#define D_NREVERSE 4 /* Reverse ed script with numbered + lines and no trailing . */ +#define D_UNIFIED 5 /* Unified diff */ + +int aflag; /* diff binary files */ +int tflag; /* expand tabs on output */ +int pflag; /* show surrounding C function */ + +/* + * Algorithm related options + */ +int hflag; /* -h, use halfhearted DIFFH */ +int bflag; /* ignore blanks in comparisons */ +int wflag; /* totally ignore blanks in comparisons */ +int iflag; /* ignore case in comparisons */ +int Bflag; /* ignore changes that consist of blank lines */ + +/* + * Options on hierarchical diffs. + */ +int lflag; /* long output format with header */ +int rflag; /* recursively trace directories */ +int sflag; /* announce files which are same */ +int Nflag; /* write text of nonexistant files */ +const char *start; /* do file only if name >= this */ + +struct xclusion { + struct xclusion *x_nxt; + const char *x_pat; +} *xflag; /* patterns to exclude from comparison */ + +/* + * Variables for -I D_IFDEF option. + */ +int wantelses; /* -E */ +char *ifdef1; /* String for -1 */ +char *ifdef2; /* String for -2 */ +char *endifname; /* What we will print on next #endif */ +int inifdef; + +/* + * Variables for -c context option. + */ +int context; /* lines of context to be printed */ + +/* + * State for exit status. + */ +int status; +int anychange; +char *tempfile1; /* used when comparing against std input */ +char *tempfile2; /* used when comparing against std input */ + +/* + * Variables for diffdir. + */ +char **diffargv; /* option list to pass to recursive diffs */ +int recdepth; /* recursion depth */ +jmp_buf recenv; /* jump stack on error */ + +struct stackblk { + struct stackblk *s_prev; + struct stackblk *s_next; +} *curstack; + +/* + * Input file names. + * With diffdir, file1 and file2 are allocated BUFSIZ space, + * and padded with a '/', and then efile0 and efile1 point after + * the '/'. + */ +char *file1, *file2, *efile1, *efile2; +struct stat stb1, stb2; + +extern const char diffh[], diff[], pr[]; +extern const char *argv0; +extern const char *progname; +int mb_cur_max; +extern int sysv3; + +/* diff.c */ +void diffany(char **); +int min(int, int); +int max(int, int); +void done(void); +void *dalloc(size_t); +void *talloc(size_t); +void *ralloc(void *, size_t); +void tfree(void *); +void purgestack(void); +void oomsg(const char *); +/* diffdir.c */ +void diffdir(char **); +int ascii(int); +/* diffreg.c */ +void diffreg(void); diff --git a/diff/diffdir.c b/diff/diffdir.c @@ -0,0 +1,993 @@ +/* + * This code contains changes by + * Gunnar Ritter, Freiburg i. Br., Germany, March 2003. All rights reserved. + * + * Conditions 1, 2, and 4 and the no-warranty notice below apply + * to these changes. + * + * + * Copyright (c) 1991 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * Redistributions of source code and documentation must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed or owned by Caldera + * International, Inc. + * Neither the name of Caldera International, Inc. nor the names of + * other contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA + * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE + * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Sccsid @(#)diffdir.c 1.30 (gritter) 1/22/06> */ +/* from 4.3BSD diffdir.c 4.9 (Berkeley) 8/28/84 */ + +#include "diff.h" +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <fcntl.h> +#include <unistd.h> +#include <time.h> +#include <signal.h> +#include "sigset.h" +#include "pathconf.h" + +#ifdef __GLIBC__ /* old glibcs don't know _XOPEN_SOURCE=600L yet */ +#ifndef S_IFSOCK +#ifdef __S_IFSOCK +#define S_IFSOCK __S_IFSOCK +#endif /* __S_IFSOCK */ +#endif /* !S_IFSOCK */ +#endif /* __GLIBC__ */ + +/* + * diff - directory comparison + */ +#define d_flags d_ino + +#define ONLY 1 /* Only in this directory */ +#define SAME 2 /* Both places and same */ +#define DIFFER 4 /* Both places and different */ +#define DIRECT 8 /* Directory */ + +struct dir { + unsigned long long d_ino; + char *d_entry; +}; + +static int header; +static char *title, *etitle; +static size_t titlesize; +static char procself[40]; + +static void setfile(char **, char **, const char *); +static void scanpr(register struct dir *, int, const char *, const char *, + const char *, const char *, const char *); +static void only(struct dir *, int); +static struct dir *setupdir(const char *); +static int entcmp(const struct dir *, const struct dir *); +static void compare(struct dir *, char **); +static void calldiff(const char *, char **); +static int useless(register const char *); +static const char *mtof(mode_t mode); +static void putN(const char *, const char *, const char *, int); +static void putNreg(const char *, const char *, time_t, int); +static void putNnorm(FILE *, const char *, const char *, + FILE *, long long, int); +static void putNedit(FILE *, const char *, const char *, + FILE *, long long, int, int); +static void putNcntx(FILE *, const char *, const char *, + time_t, FILE *, long long, int); +static void putNunif(FILE *, const char *, const char *, + time_t, FILE *, long long, int); +static void putNhead(FILE *, const char *, const char *, time_t, int, + const char *, const char *); +static void putNdata(FILE *, FILE *, int, int); +static void putNdir(const char *, const char *, int); +static long long linec(const char *, FILE *); +static char *mkpath(const char *, const char *); +static void mktitle(void); +static int xclude(const char *); + +void +diffdir(char **argv) +{ + register struct dir *d1, *d2; + struct dir *dir1, *dir2; + register int i, n; + int cmp; + + if (opt == D_IFDEF) { + fprintf(stderr, "%s: can't specify -I with directories\n", + progname); + done(); + } + status = 0; + if (opt == D_EDIT && (sflag || lflag)) + fprintf(stderr, + "%s: warning: shouldn't give -s or -l with -e\n", + progname); + for (n = 6, i = 1; diffargv[i+2]; i++) + n += strlen(diffargv[i]) + 1; + if (n > titlesize) + title = ralloc(title, titlesize = n); + title[0] = 0; + strcpy(title, "diff "); + for (i = 1; diffargv[i+2]; i++) { + if (!strcmp(diffargv[i], "-")) + continue; /* was -S, dont look silly */ + strcat(title, diffargv[i]); + strcat(title, " "); + } + for (etitle = title; *etitle; etitle++) + ; + /* + * This works around a bug present in (at least) Solaris 8 and + * 9: If exec() is called with /proc/self/object/a.out, the + * process hangs. It is possible, though, to use the executable + * of another process. So the parent diff is used instead of the + * forked child. + */ + i = getpid(); + snprintf(procself, sizeof procself, +#if defined (__linux__) + "/proc/%d/exe", +#elif defined (__FreeBSD__) || defined (__DragonFly__) || defined (__APPLE__) + "/proc/%d/file", +#else /* !__linux__, !__FreeBSD__, !__APPLE__ */ + "/proc/%d/object/a.out", +#endif /* !__linux__, !__FreeBSD__, !__APPLE__ */ + i); + setfile(&file1, &efile1, file1); + setfile(&file2, &efile2, file2); + argv[0] = file1; + argv[1] = file2; + dir1 = setupdir(file1); + dir2 = setupdir(file2); + d1 = dir1; d2 = dir2; + while (d1->d_entry != 0 || d2->d_entry != 0) { + if (d1->d_entry && useless(d1->d_entry)) { + d1++; + continue; + } + if (d2->d_entry && useless(d2->d_entry)) { + d2++; + continue; + } + if (d1->d_entry == 0) + cmp = 1; + else if (d2->d_entry == 0) + cmp = -1; + else + cmp = strcmp(d1->d_entry, d2->d_entry); + if (cmp < 0) { + if (lflag && !(Nflag&1)) + d1->d_flags |= ONLY; + else if (Nflag&1 || opt == D_NORMAL || + opt == D_CONTEXT || opt == D_UNIFIED) + only(d1, 1); + d1++; + } else if (cmp == 0) { + compare(d1, argv); + d1++; + d2++; + } else { + if (lflag && !(Nflag&2)) + d2->d_flags |= ONLY; + else if (Nflag&2 || opt == D_NORMAL || + opt == D_CONTEXT || opt == D_UNIFIED) + only(d2, 2); + d2++; + } + } + if (lflag) { + scanpr(dir1, ONLY, "Only in %.*s", file1, efile1, 0, 0); + scanpr(dir2, ONLY, "Only in %.*s", file2, efile2, 0, 0); + scanpr(dir1, SAME, "Common identical files in %.*s and %.*s", + file1, efile1, file2, efile2); + scanpr(dir1, DIFFER, "Binary files which differ in %.*s and %.*s", + file1, efile1, file2, efile2); + scanpr(dir1, DIRECT, "Common subdirectories of %.*s and %.*s", + file1, efile1, file2, efile2); + } + if (rflag) { + if (header && lflag) + printf("\f"); + for (d1 = dir1; d1->d_entry; d1++) { + if ((d1->d_flags & DIRECT) == 0) + continue; + strcpy(efile1, d1->d_entry); + strcpy(efile2, d1->d_entry); + calldiff(0, argv); + } + } +} + +static void +setfile(char **fpp, char **epp, const char *file) +{ + register char *cp; + int n; + + if ((n = pathconf(file, _PC_PATH_MAX)) < 1024) + n = 1024; + *fpp = dalloc(strlen(file) + 2 + n); + if (*fpp == 0) { + oomsg(": ran out of memory\n"); + exit(1); + } + strcpy(*fpp, file); + for (cp = *fpp; *cp; cp++) + continue; + *cp++ = '/'; + *cp = '\0'; + *epp = cp; +} + +static void +scanpr(register struct dir *dp, int test, const char *title, + const char *file1, const char *efile1, + const char *file2, const char *efile2) +{ + int titled = 0; + + for (; dp->d_entry; dp++) { + if ((dp->d_flags & test) == 0) + continue; + if (titled == 0) { + if (header == 0) + header = 1; + else + printf("\n"); + printf(title, + efile1 - file1 - 1, file1, + efile2 - file2 - 1, file2); + printf(":\n"); + titled = 1; + } + printf("\t%s\n", dp->d_entry); + } +} + +static void +only(struct dir *dp, int which) +{ + char *file = which == 1 ? file1 : file2; + char *other = which == 1 ? file2 : file1; + char *efile = which == 1 ? efile1 : efile2; + char *eother = which == 1 ? efile2 : efile1; + + if (Nflag&which) { + char c = file[efile - file - 1]; + char d = other[eother - other - 1]; + file[efile - file - 1] = '\0'; + other[eother - other - 1] = '\0'; + putN(file, other, dp->d_entry, which); + file[efile - file - 1] = c; + other[eother - other - 1] = d; + } else + printf("Only in %.*s: %s\n", (int)(efile - file - 1), file, + dp->d_entry); + status = 1; +} + +static struct dir * +setupdir(const char *cp) +{ + register struct dir *dp = 0, *ep; + register struct dirent *rp; + register int nitems; + DIR *dirp; + + dirp = opendir(cp); + if (dirp == NULL) { + fprintf(stderr, "%s: %s: %s\n", progname, cp, strerror(errno)); + done(); + } + nitems = 0; + dp = dalloc(sizeof (struct dir)); + if (dp == 0) { + oomsg(": ran out of memory\n"); + status = 2; + done(); + } + while (rp = readdir(dirp)) { + if (xflag && xclude(rp->d_name)) + continue; + ep = &dp[nitems++]; + ep->d_entry = 0; + ep->d_flags = 0; + ep->d_entry = dalloc(strlen(rp->d_name) + 1); + if (ep->d_entry == 0) { + oomsg(": out of memory\n"); + status = 2; + done(); + } + strcpy(ep->d_entry, rp->d_name); + dp = ralloc(dp, (nitems + 1) * sizeof (struct dir)); + } + dp[nitems].d_entry = 0; /* delimiter */ + closedir(dirp); + qsort(dp, nitems, sizeof (struct dir), + (int (*)(const void *, const void *))entcmp); + return (dp); +} + +static int +entcmp(const struct dir *d1, const struct dir *d2) +{ + return (strcmp(d1->d_entry, d2->d_entry)); +} + +static void +compare(struct dir *dp, char **argv) +{ + register int i, j; + int f1 = -1, f2 = -1; + mode_t fmt1, fmt2; + struct stat stb1, stb2; + char buf1[BUFSIZ], buf2[BUFSIZ]; + + strcpy(efile1, dp->d_entry); + strcpy(efile2, dp->d_entry); + if (stat(file1, &stb1) < 0 || (fmt1 = stb1.st_mode&S_IFMT) == S_IFREG && + (f1 = open(file1, O_RDONLY)) < 0) { + perror(file1); + status = 2; + return; + } + if (stat(file2, &stb2) < 0 || (fmt2 = stb2.st_mode&S_IFMT) == S_IFREG && + (f2 = open(file2, O_RDONLY)) < 0) { + perror(file2); + close(f1); + status = 2; + return; + } + if (fmt1 != S_IFREG || fmt2 != S_IFREG) { + if (fmt1 == fmt2) { + switch (fmt1) { + case S_IFDIR: + dp->d_flags = DIRECT; + if (lflag || opt == D_EDIT) + goto closem; + if (opt != D_UNIFIED) + printf("Common subdirectories: " + "%s and %s\n", + file1, file2); + goto closem; + case S_IFBLK: + case S_IFCHR: + if (stb1.st_rdev == stb2.st_rdev) + goto same; + printf("Special files %s and %s differ\n", + file1, file2); + break; + case S_IFIFO: + if (stb1.st_dev == stb2.st_dev && + stb1.st_ino == stb2.st_ino) + goto same; + printf("Named pipes %s and %s differ\n", + file1, file2); + break; + default: + printf("Don't know how to compare " + "%ss %s and %s\n", + mtof(fmt1), file1, file2); + } + } else + printf("File %s is a %s while file %s is a %s\n", + file1, mtof(fmt1), file2, mtof(fmt2)); + if (lflag) + dp->d_flags |= DIFFER; + status = 1; + goto closem; + } + if (stb1.st_size != stb2.st_size) + goto notsame; + if (stb1.st_dev == stb2.st_dev && stb1.st_ino == stb2.st_ino) + goto same; + for (;;) { + i = read(f1, buf1, BUFSIZ); + j = read(f2, buf2, BUFSIZ); + if (i < 0 || j < 0 || i != j) + goto notsame; + if (i == 0 && j == 0) + goto same; + for (j = 0; j < i; j++) + if (buf1[j] != buf2[j]) + goto notsame; + } +same: + if (sflag == 0) + goto closem; + if (lflag) + dp->d_flags = SAME; + else + printf("Files %s and %s are identical\n", file1, file2); + goto closem; +notsame: + if (!aflag && (!ascii(f1) || !ascii(f2))) { + if (lflag) + dp->d_flags |= DIFFER; + else if (opt == D_NORMAL || opt == D_CONTEXT || + opt == D_UNIFIED) + printf("Binary files %s and %s differ\n", + file1, file2); + status = 1; + goto closem; + } + close(f1); close(f2); + anychange = 1; + if (lflag) + calldiff(title, argv); + else { + if (opt == D_EDIT) { + printf("ed - %s << '-*-END-*-'\n", dp->d_entry); + calldiff(0, argv); + } else { + printf("%s%s %s\n", title, file1, file2); + calldiff(0, argv); + } + if (opt == D_EDIT) + printf("w\nq\n-*-END-*-\n"); + } + return; +closem: + close(f1); close(f2); +} + +static void +stackdiff(char **argv) +{ + int oanychange; + char *ofile1, *ofile2, *oefile1, *oefile2; + struct stat ostb1, ostb2; + struct stackblk *ocurstack; + char *oargv[2]; + int oheader; + char *otitle, *oetitle; + size_t otitlesize; + jmp_buf orecenv; + + (void)&oargv; + recdepth++; + oanychange = anychange; + ofile1 = file1; + ofile2 = file2; + oefile1 = efile1; + oefile2 = efile2; + ostb1 = stb1; + ostb2 = stb2; + ocurstack = curstack; + oargv[0] = argv[0]; + oargv[1] = argv[1]; + oheader = header; + otitle = title; + oetitle = etitle; + otitlesize = titlesize; + memcpy(orecenv, recenv, sizeof orecenv); + + anychange = 0; + file1 = argv[0]; + file2 = argv[1]; + efile1 = NULL; + efile2 = NULL; + curstack = NULL; + header = 0; + title = NULL; + etitle = NULL; + titlesize = 0; + + if (setjmp(recenv) == 0) + diffany(argv); + purgestack(); + + anychange = oanychange; + file1 = ofile1; + file2 = ofile2; + efile1 = oefile1; + efile2 = oefile2; + stb1 = ostb1; + stb2 = ostb2; + curstack = ocurstack; + argv[0] = oargv[0]; + argv[1] = oargv[1]; + header = oheader; + title = otitle; + etitle = oetitle; + titlesize = otitlesize; + memcpy(recenv, orecenv, sizeof recenv); + recdepth--; +} + +static const char *prargs[] = { "pr", "-h", 0, "-f", 0, 0 }; + +static void +calldiff(const char *wantpr, char **argv) +{ + int pid, cstatus, cstatus2, pv[2]; + + if (wantpr == NULL && hflag == 0) { + stackdiff(argv); + return; + } + prargs[2] = wantpr; + fflush(stdout); + if (wantpr) { + mktitle(); + pipe(pv); + pid = fork(); + if (pid == -1) { + fprintf(stderr, "No more processes\n"); + done(); + } + if (pid == 0) { + close(0); + dup(pv[0]); + close(pv[0]); + close(pv[1]); + execvp(pr, (char **)prargs); + perror(pr); + done(); + } + } + pid = fork(); + if (pid == -1) { + fprintf(stderr, "%s: No more processes\n", progname); + done(); + } + if (pid == 0) { + if (wantpr) { + close(1); + dup(pv[1]); + close(pv[0]); + close(pv[1]); + } + execv(procself, diffargv); + execv(argv0, diffargv); + execvp(diff, diffargv); + perror(diff); + done(); + } + if (wantpr) { + close(pv[0]); + close(pv[1]); + } + while (wait(&cstatus) != pid) + continue; + if (cstatus != 0) { + if (WIFEXITED(cstatus) && WEXITSTATUS(cstatus) == 1) + status = 1; + else + status = 2; + } + while (wait(&cstatus2) != -1) + continue; +/* + if ((status >> 8) >= 2) + done(); +*/ +} + +int +ascii(int f) +{ + char buf[BUFSIZ]; + register int cnt; + register char *cp; + + lseek(f, 0, 0); + cnt = read(f, buf, BUFSIZ); + cp = buf; + while (--cnt >= 0) + if (*cp++ == '\0') + return (0); + return (1); +} + +/* + * THIS IS CRUDE. + */ +static int +useless(register const char *cp) +{ + + if (cp[0] == '.') { + if (cp[1] == '\0') + return (1); /* directory "." */ + if (cp[1] == '.' && cp[2] == '\0') + return (1); /* directory ".." */ + } + if (start && strcmp(start, cp) > 0) + return (1); + return (0); +} + +static const char * +mtof(mode_t mode) +{ + switch (mode) { + case S_IFDIR: + return "directory"; + case S_IFCHR: + return "character special file"; + case S_IFBLK: + return "block special file"; + case S_IFREG: + return "plain file"; + case S_IFIFO: + return "named pipe"; +#ifdef S_IFSOCK + case S_IFSOCK: + return "socket"; +#endif /* S_IFSOCK */ + default: + return "unknown type"; + } +} + +static void +putN(const char *dir, const char *odir, const char *file, int which) +{ + struct stat st; + char *path; + char *opath; + + path = mkpath(dir, file); + opath = mkpath(odir, file); + if (stat(path, &st) < 0) { + fprintf(stderr, "%s: %s: %s\n", progname, path, + strerror(errno)); + status = 2; + goto out; + } + switch (st.st_mode & S_IFMT) { + case S_IFREG: + putNreg(path, opath, st.st_mtime, which); + break; + case S_IFDIR: + putNdir(path, opath, which); + break; + default: + printf("Only in %s: %s\n", dir, file); + } +out: tfree(path); + tfree(opath); +} + +static void +putNreg(const char *fn, const char *on, time_t mtime, int which) +{ + long long lines; + FILE *fp; + FILE *op; + void (*opipe)(int) = SIG_DFL; + pid_t pid = 0; + + if ((fp = fopen(fn, "r")) == NULL) { + fprintf(stderr, "%s: %s: %s\n", progname, fn, strerror(errno)); + status = 2; + return; + } + if ((lines = linec(fn, fp)) == 0 || fseek(fp, 0, SEEK_SET) != 0) + goto out; + if (lflag) { + int pv[2]; + opipe = sigset(SIGPIPE, SIG_IGN); + fflush(stdout); + prargs[2] = title; + pipe(pv); + switch (pid = fork()) { + case -1: + fprintf(stderr, "No more processes\n"); + done(); + /*NOTREACHED*/ + case 0: + close(0); + dup(pv[0]); + close(pv[0]); + close(pv[1]); + execvp(pr, (char **)prargs); + perror(pr); + done(); + } + close(pv[0]); + op = fdopen(pv[1], "w"); + } else + op = stdout; + fprintf(op, "%.*s %s %s\n", (int)(etitle - title - 1), title, + which == 1 ? fn : on, + which == 1 ? on : fn); + switch (opt) { + case D_NORMAL: + putNnorm(op, fn, on, fp, lines, which); + break; + case D_EDIT: + putNedit(op, fn, on, fp, lines, which, 0); + break; + case D_REVERSE: + putNedit(op, fn, on, fp, lines, which, 1); + break; + case D_CONTEXT: + putNcntx(op, fn, on, mtime, fp, lines, which); + break; + case D_NREVERSE: + putNedit(op, fn, on, fp, lines, which, 2); + break; + case D_UNIFIED: + putNunif(op, fn, on, mtime, fp, lines, which); + break; + } + if (lflag) { + fclose(op); + while (wait(NULL) != pid); + sigset(SIGPIPE, opipe); + } +out: fclose(fp); +} + +static void +putNnorm(FILE *op, const char *fn, const char *on, + FILE *fp, long long lines, int which) +{ + int pfx; + + if (which == 1) { + fprintf(op, "1,%lldd0\n", lines); + pfx = '<'; + } else { + fprintf(op, "0a1,%lld\n", lines); + pfx = '>'; + } + putNdata(op, fp, pfx, ' '); +} + +static void +putNedit(FILE *op, const char *fn, const char *on, + FILE *fp, long long lines, int which, int reverse) +{ + switch (reverse) { + case 0: + if (which == 1) + fprintf(op, "1,%lldd\n", lines); + else { + fprintf(op, "0a\n"); + putNdata(op, fp, 0, 0); + fprintf(op, ".\n"); + } + break; + case 1: + if (which == 1) + fprintf(op, "d1 %lld\n", lines); + else { + fprintf(op, "a0\n"); + putNdata(op, fp, 0, 0); + fprintf(op, ".\n"); + } + break; + case 2: + if (which == 1) + fprintf(op, "d1 %lld\n", lines); + else { + fprintf(op, "a0 %lld\n", lines); + putNdata(op, fp, 0, 0); + } + break; + } +} + +static void +putNcntx(FILE *op, const char *fn, const char *on, time_t mtime, + FILE *fp, long long lines, int which) +{ + putNhead(op, fn, on, mtime, which, "***", "---"); + fprintf(op, "***************\n*** "); + if (which == 1) + fprintf(op, "1,%lld", lines); + else + putc('0', op); + fprintf(op, " ****\n"); + if (which != 1) + fprintf(op, "--- 1,%lld ----\n", lines); + putNdata(op, fp, which == 1 ? '-' : '+', ' '); + if (which == 1) + fprintf(op, "--- 0 ----\n"); +} + +static void +putNunif(FILE *op, const char *fn, const char *on, time_t mtime, + FILE *fp, long long lines, int which) +{ + putNhead(op, fn, on, mtime, which, "---", "+++"); + fprintf(op, "@@ "); + fprintf(op, which == 1 ? "-1,%lld +0,0" : "-0,0 +1,%lld", lines); + fprintf(op, " @@\n"); + putNdata(op, fp, which == 1 ? '-' : '+', 0); +} + +static void +putNhead(FILE *op, const char *fn, const char *on, time_t mtime, int which, + const char *p1, const char *p2) +{ + time_t t1, t2; + const char *f1, *f2; + + t1 = which == 1 ? mtime : 0; + t2 = which == 1 ? 0 : mtime; + f1 = which == 1 ? fn : on; + f2 = which == 1 ? on : fn; + fprintf(op, "%s %s\t%s", p1, f1, ctime(&t1)); + fprintf(op, "%s %s\t%s", p2, f2, ctime(&t2)); +} + +static void +putNdata(FILE *op, FILE *fp, int pfx, int sec) +{ + int c, lastc = '\n', col = 0; + + while ((c = getc(fp)) != EOF) { + if (lastc == '\n') { + col = 0; + if (pfx) + putc(pfx, op); + if (sec) + putc(sec, op); + } + if (c == '\t' && tflag) { + do + putc(' ', op); + while (++col & 7); + } else { + putc(c, op); + col++; + } + lastc = c; + } + if (lastc != '\n') { + if (aflag) + fprintf(op, "\n\\ No newline at end of file\n"); + else + putc('\n', op); + } +} + +static void +putNdir(const char *fn, const char *on, int which) +{ + DIR *Dp; + struct dirent *dp; + + if ((Dp = opendir(fn)) == NULL) { + fprintf(stderr, "%s: %s: %s\n", progname, fn, strerror(errno)); + status = 2; + return; + } + while ((dp = readdir(Dp)) != NULL) { + if (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || + dp->d_name[1] == '.' && + dp->d_name[2] == '\0')) + continue; + if (xflag && xclude(dp->d_name)) + continue; + putN(fn, on, dp->d_name, which); + } + closedir(Dp); +} + +static long long +linec(const char *fn, FILE *fp) +{ + int c, lastc = '\n'; + long long cnt = 0; + + while ((c = getc(fp)) != EOF) { + if (c == '\n') + cnt++; + lastc = c; + } + if (lastc != '\n') { + if (!aflag) + fprintf(stderr, + "Warning: missing newline at end of file %s\n", + fn); + cnt++; + } + return cnt; +} + +static char * +mkpath(const char *dir, const char *file) +{ + char *path, *pp; + const char *cp; + + pp = path = talloc(strlen(dir) + strlen(file) + 2); + for (cp = dir; *cp; cp++) + *pp++ = *cp; + if (pp > path && pp[-1] != '/') + *pp++ = '/'; + for (cp = file; *cp; cp++) + *pp++ = *cp; + *pp = '\0'; + return path; +} + +static void +mktitle(void) +{ + int n; + + n = strlen(file1) + strlen(file2) + 2; + if (etitle - title + n < titlesize) { + titlesize = n; + n = etitle - title; + title = ralloc(title, titlesize); + etitle = &title[n]; + } + sprintf(etitle, "%s %s", file1, file2); +} + +static int +xclude(const char *fn) +{ + extern int gmatch(const char *, const char *); + struct xclusion *xp; + + for (xp = xflag; xp; xp = xp->x_nxt) + if (gmatch(fn, xp->x_pat)) + return 1; + return 0; +} diff --git a/diff/diffh.c b/diff/diffh.c @@ -0,0 +1,410 @@ +/* + * This code contains changes by + * Gunnar Ritter, Freiburg i. Br., Germany, March 2003. All rights reserved. + * + * Conditions 1, 2, and 4 and the no-warranty notice below apply + * to these changes. + * + * + * Copyright (c) 1991 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * Redistributions of source code and documentation must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed or owned by Caldera + * International, Inc. + * Neither the name of Caldera International, Inc. nor the names of + * other contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA + * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE + * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 +#define USED __attribute__ ((used)) +#elif defined __GNUC__ +#define USED __attribute__ ((unused)) +#else +#define USED +#endif +static const char sccsid[] USED = "@(#)diffh.sl 1.11 (gritter) 5/29/05"; + +/* from 4.3BSD diffh.c 4.4 11/27/85> */ + +#include <stdio.h> +#include <ctype.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#include <unistd.h> +#include <locale.h> +#include <wchar.h> +#include <wctype.h> + +#include <iblok.h> +#include <mbtowi.h> + +#define C 3 +#define RANGE 30 +#define INF 16384 + +#define next(wc, s, n) (*(s) & 0200 ? ((n) = mbtowi(&(wc), (s), mb_cur_max), \ + (n) = ((n) > 0 ? (n) : (n) < 0 ? (wc=WEOF, 1) : 1)) :\ + ((wc) = *(s) & 0377, (n) = 1)) + +static char *text[2][RANGE]; +static size_t size[2][RANGE]; +static long long lineno[2] = {1, 1}; /*no. of 1st stored line in each file*/ +static int ntext[2]; /*number of stored lines in each*/ +static long long n0,n1; /*scan pointer in each*/ +static int bflag; +static int mb_cur_max; +static int debug = 0; +static struct iblok *file[2]; +static int eof[2]; + +static char *getl(int, long long); +static void clrl(int, long long); +static void movstr(int, int, int); +static int easysynch(void); +static int output(int, int); +static void change(long long, int, long long, int, const char *); +static void range(long long, int); +static int cmp(const char *, const char *); +static struct iblok *dopen(const char *, const char *); +static void progerr(const char *); +static void error(const char *, const char *); +static int hardsynch(void); +static void *lrealloc(void *, size_t); + + /* return pointer to line n of file f*/ +static char * +getl(int f, long long n) +{ + register int delta, nt; + size_t len; + + delta = n - lineno[f]; + nt = ntext[f]; + if(delta<0) + progerr("1"); + if(delta<nt) + return(text[f][delta]); + if(delta>nt) + progerr("2"); + if(nt>=RANGE) + progerr("3"); + if(eof[f]) + return(NULL); + len = ib_getlin(file[f], &text[f][nt], &size[f][nt], lrealloc); + if (len != 0) { + ntext[f]++; + return(text[f][nt]); + } else { + eof[f]++; + return NULL; + } +} + + /*remove thru line n of file f from storage*/ +static void +clrl(int f,long long n) +{ + register long long i,j; + j = n-lineno[f]+1; + for(i=0;i+j<ntext[f];i++) + movstr(f, i+j, i); + lineno[f] = n+1; + ntext[f] -= j; +} + +static void +movstr(register int f, register int i, register int j) +{ + free(text[f][j]); + text[f][j] = text[f][i]; + size[f][j] = size[f][i]; + text[f][i] = 0; + size[f][i] = 0; +} + +int +main(int argc,char **argv) +{ + char *s0,*s1; + register int c, status = 0; + + setlocale(LC_CTYPE, ""); + mb_cur_max = MB_CUR_MAX; + while((c=getopt(argc,argv,":b")) != EOF) { + switch (c) { + case 'b': + bflag++; + break; + } + } + if(argc-optind!=2) + error("must have 2 file arguments",""); + file[0] = dopen(argv[optind],argv[optind+1]); + file[1] = dopen(argv[optind+1],argv[optind]); + for(;;) { + s0 = getl(0,++n0); + s1 = getl(1,++n1); + if(s0==NULL||s1==NULL) + break; + if(cmp(s0,s1)!=0) { + if(!easysynch()&&!hardsynch()) + progerr("5"); + status = 1; + } else { + clrl(0,n0); + clrl(1,n1); + } + } + if(s0==NULL&&s1==NULL) + exit(status); + if(s0==NULL) + output(-1,INF); + if(s1==NULL) + output(INF,-1); + return (1); +} + + /* synch on C successive matches*/ +static int +easysynch(void) +{ + int i,j; + register int k,m; + char *s0,*s1; + for(i=j=1;i<RANGE&&j<RANGE;i++,j++) { + s0 = getl(0,n0+i); + if(s0==NULL) + return(output(INF,INF)); + for(k=C-1;k<j;k++) { + for(m=0;m<C;m++) + if(cmp(getl(0,n0+i-m), + getl(1,n1+k-m))!=0) + goto cont1; + return(output(i-C,k-C)); +cont1: ; + } + s1 = getl(1,n1+j); + if(s1==NULL) + return(output(INF,INF)); + for(k=C-1;k<=i;k++) { + for(m=0;m<C;m++) + if(cmp(getl(0,n0+k-m), + getl(1,n1+j-m))!=0) + goto cont2; + return(output(k-C,j-C)); +cont2: ; + } + } + return(0); +} + +static int +output(int a,int b) +{ + register int i; + char *s; + if(a<0) + change(n0-1,0,n1,b,"a"); + else if(b<0) + change(n0,a,n1-1,0,"d"); + else + change(n0,a,n1,b,"c"); + for(i=0;i<=a;i++) { + s = getl(0,n0+i); + if(s==NULL) + break; + printf("< %s",s); + clrl(0,n0+i); + } + n0 += i-1; + if(a>=0&&b>=0) + printf("---\n"); + for(i=0;i<=b;i++) { + s = getl(1,n1+i); + if(s==NULL) + break; + printf("> %s",s); + clrl(1,n1+i); + } + n1 += i-1; + return(1); +} + +static void +change(long long a,int b,long long c,int d,const char *s) +{ + range(a,b); + printf("%s",s); + range(c,d); + printf("\n"); +} + +static void +range(long long a,int b) +{ + if(b==INF) + printf("%lld,$",a); + else if(b==0) + printf("%lld",a); + else + printf("%lld,%lld",a,a+b); +} + +static int +cmp(const char *s,const char *t) +{ + if(debug) + printf("%s:%s\n",s,t); + for(;;){ + if(bflag) { + if (mb_cur_max > 1) { + wint_t wc, wd; + int n, m; + + if (next(wc, s, n), next(wd, t, m), + iswspace(wc) && iswspace(wd)) { + while (s += n, next(wc, s, n), + iswspace(wc)); + while (t += m, next(wd, t, m), + iswspace(wd)); + } + } else { + if (isspace(*s)&&isspace(*t)) { + while(isspace(*++s)) ; + while(isspace(*++t)) ; + } + } + } + if(*s!=*t||*s==0) + break; + s++; + t++; + } + return((*s&0377)-(*t&0377)); +} + +static struct iblok * +dopen(const char *f1,const char *f2) +{ + struct iblok *ip; + char *b=0,*bptr; + const char *eptr; + struct stat statbuf; + if(cmp(f1,"-")==0) + if(cmp(f2,"-")==0) + error("can't do - -",""); + else + return(ib_alloc(0, 0)); + if(stat(f1,&statbuf)==-1) + error("can't access ",f1); + if((statbuf.st_mode&S_IFMT)==S_IFDIR) { + b = lrealloc(0, strlen(f1) + strlen(f2) + 2); + for(bptr=b;*bptr= *f1++;bptr++) ; + *bptr++ = '/'; + for(eptr=f2;*eptr;eptr++) + if(*eptr=='/'&&eptr[1]!=0&&eptr[1]!='/') + f2 = eptr+1; + while(*bptr++= *f2++) ; + f1 = b; + } + ip = ib_open(f1,0); + if(ip==NULL) + error("can't open",f1); + if (b) + free(b); + return(ip); +} + +static void +progerr(const char *s) +{ + error("program error ",s); +} + +static void +error(const char *s,const char *t) +{ + fprintf(stderr,"diffh: %s%s\n",s,t); + exit(2); +} + + /*stub for resychronization beyond limits of text buf*/ +static int +hardsynch(void) +{ + change(n0,INF,n1,INF,"c"); + printf("---change record omitted\n"); + error("can't resynchronize",""); + return(0); +} + +static void * +lrealloc(void *op, size_t size) +{ + void *np; + + if ((np = realloc(op, size)) == NULL) { + write(2, "diffh: line too long\n", 21); + _exit(1); + } + return np; +} diff --git a/diff/diffreg.c b/diff/diffreg.c @@ -0,0 +1,1629 @@ +/* + * This code contains changes by + * Gunnar Ritter, Freiburg i. Br., Germany, March 2003. All rights reserved. + * + * Conditions 1, 2, and 4 and the no-warranty notice below apply + * to these changes. + * + * + * Copyright (c) 1991 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * Redistributions of source code and documentation must retain the + * above copyright notice, this list of conditions and the following + * disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed or owned by Caldera + * International, Inc. + * Neither the name of Caldera International, Inc. nor the names of + * other contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA + * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE + * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Sccsid @(#)diffreg.c 1.30 (gritter) 3/15/07> */ +/* from 4.3BSD diffreg.c 4.16 3/29/86 */ + +#include "diff.h" +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <time.h> +#include <signal.h> +#include "sigset.h" +#include <wchar.h> +#include <wctype.h> +#include <inttypes.h> +#include "mbtowi.h" +/* + * diff - compare two files. + */ + +/* + * Uses an algorithm due to Harold Stone, which finds + * a pair of longest identical subsequences in the two + * files. + * + * The major goal is to generate the match vector J. + * J[i] is the index of the line in file1 corresponding + * to line i file0. J[i] = 0 if there is no + * such line in file1. + * + * Lines are hashed so as to work in core. All potential + * matches are located by sorting the lines of each file + * on the hash (called ``value''). In particular, this + * collects the equivalence classes in file1 together. + * Subroutine equiv replaces the value of each line in + * file0 by the index of the first element of its + * matching equivalence in (the reordered) file1. + * To save space equiv squeezes file1 into a single + * array member in which the equivalence classes + * are simply concatenated, except that their first + * members are flagged by changing sign. + * + * Next the indices that point into member are unsorted into + * array class according to the original order of file0. + * + * The cleverness lies in routine stone. This marches + * through the lines of file0, developing a vector klist + * of "k-candidates". At step i a k-candidate is a matched + * pair of lines x,y (x in file0 y in file1) such that + * there is a common subsequence of length k + * between the first i lines of file0 and the first y + * lines of file1, but there is no such subsequence for + * any smaller y. x is the earliest possible mate to y + * that occurs in such a subsequence. + * + * Whenever any of the members of the equivalence class of + * lines in file1 matable to a line in file0 has serial number + * less than the y of some k-candidate, that k-candidate + * with the smallest such y is replaced. The new + * k-candidate is chained (via pred) to the current + * k-1 candidate so that the actual subsequence can + * be recovered. When a member has serial number greater + * that the y of all k-candidates, the klist is extended. + * At the end, the longest subsequence is pulled out + * and placed in the array J by unravel + * + * With J in hand, the matches there recorded are + * check'ed against reality to assure that no spurious + * matches have crept in due to hashing. If they have, + * they are broken, and "jackpot" is recorded--a harmless + * matter except that a true match for a spuriously + * mated line may now be unnecessarily reported as a change. + * + * Much of the complexity of the program comes simply + * from trying to minimize core utilization and + * maximize the range of doable problems by dynamically + * allocating what is needed and reusing what is not. + * The core requirements for problems larger than somewhat + * are (in words) 2*length(file0) + length(file1) + + * 3*(number of k-candidates installed), typically about + * 6n words for files of length n. + */ + +#define prints(s) fputs(s,stdout) + +static FILE *input[2]; +static char mbuf[2][MB_LEN_MAX+1]; +static char *mcur[2]; +static char *mend[2]; +static int incompl[2]; + +struct cand { + long x; + long y; + long pred; +} cand; +static struct line { + long serial; + long value;