aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncaen <mail@duncano.de>2017-03-03 15:50:52 +0100
committerDuncaen <mail@duncano.de>2017-03-04 22:40:01 +0100
commit73891ba0d59bd29c8e43089110b4b926c6d761f1 (patch)
tree00e8ff2483e0facae6d2b111a0629b6f19be7ed0
downloadlobase-73891ba0d59bd29c8e43089110b4b926c6d761f1.tar.gz
initial import
-rw-r--r--.gitignore2
-rw-r--r--Makefile15
-rw-r--r--OPENBSD_BRANCH1
-rw-r--r--bin/Makefile12
-rw-r--r--bin/cat/CVS/Entries4
-rw-r--r--bin/cat/CVS/Repository1
-rw-r--r--bin/cat/CVS/Root1
-rw-r--r--bin/cat/Makefile6
-rw-r--r--bin/cat/Makefile,v180
-rw-r--r--bin/cat/cat.1185
-rw-r--r--bin/cat/cat.c249
-rw-r--r--bin/chmod/Makefile18
-rw-r--r--bin/chmod/chflags.1174
-rw-r--r--bin/chmod/chgrp.1140
-rw-r--r--bin/chmod/chmod.1397
-rw-r--r--bin/chmod/chmod.c377
-rw-r--r--bin/chmod/chown.8172
-rw-r--r--bin/cp/Makefile6
-rw-r--r--bin/cp/cp.1250
-rw-r--r--bin/cp/cp.c454
-rw-r--r--bin/cp/extern.h54
-rw-r--r--bin/cp/utils.c320
-rw-r--r--bin/date/Makefile8
-rw-r--r--bin/date/date.1248
-rw-r--r--bin/date/date.c277
-rw-r--r--bin/dd/Makefile6
-rw-r--r--bin/dd/args.c470
-rw-r--r--bin/dd/conv.c274
-rw-r--r--bin/dd/conv_tab.c166
-rw-r--r--bin/dd/dd.1380
-rw-r--r--bin/dd/dd.c412
-rw-r--r--bin/dd/dd.h98
-rw-r--r--bin/dd/extern.h64
-rw-r--r--bin/dd/misc.c121
-rw-r--r--bin/dd/position.c165
-rw-r--r--bin/df/Makefile8
-rw-r--r--bin/df/df.1179
-rw-r--r--bin/df/df.c461
-rw-r--r--bin/df/ext2fs_df.c103
-rw-r--r--bin/df/ffs_df.c95
-rw-r--r--bin/domainname/Makefile5
-rw-r--r--bin/domainname/domainname.170
-rw-r--r--bin/domainname/domainname.c77
-rw-r--r--bin/echo/Makefile5
-rw-r--r--bin/echo/echo.1100
-rw-r--r--bin/echo/echo.c64
-rw-r--r--bin/ed/Makefile7
-rw-r--r--bin/ed/POSIX91
-rw-r--r--bin/ed/README22
-rw-r--r--bin/ed/USD.doc/09.edtut/Makefile10
-rw-r--r--bin/ed/USD.doc/09.edtut/e.mac72
-rw-r--r--bin/ed/USD.doc/09.edtut/e074
-rw-r--r--bin/ed/USD.doc/09.edtut/e1271
-rw-r--r--bin/ed/USD.doc/09.edtut/e2463
-rw-r--r--bin/ed/USD.doc/09.edtut/e3417
-rw-r--r--bin/ed/USD.doc/09.edtut/e4303
-rw-r--r--bin/ed/USD.doc/09.edtut/e5310
-rw-r--r--bin/ed/USD.doc/09.edtut/e6277
-rw-r--r--bin/ed/USD.doc/09.edtut/e7227
-rw-r--r--bin/ed/USD.doc/10.edadv/Makefile10
-rw-r--r--bin/ed/USD.doc/10.edadv/ae.mac86
-rw-r--r--bin/ed/USD.doc/10.edadv/ae0102
-rw-r--r--bin/ed/USD.doc/10.edadv/ae1104
-rw-r--r--bin/ed/USD.doc/10.edadv/ae21015
-rw-r--r--bin/ed/USD.doc/10.edadv/ae3488
-rw-r--r--bin/ed/USD.doc/10.edadv/ae4218
-rw-r--r--bin/ed/USD.doc/10.edadv/ae5359
-rw-r--r--bin/ed/USD.doc/10.edadv/ae6519
-rw-r--r--bin/ed/USD.doc/10.edadv/ae7219
-rw-r--r--bin/ed/USD.doc/10.edadv/ae955
-rw-r--r--bin/ed/buf.c290
-rw-r--r--bin/ed/ed.1851
-rw-r--r--bin/ed/ed.h201
-rw-r--r--bin/ed/glbl.c212
-rw-r--r--bin/ed/io.c355
-rw-r--r--bin/ed/main.c1445
-rw-r--r--bin/ed/re.c139
-rw-r--r--bin/ed/sub.c263
-rw-r--r--bin/ed/test/=.err1
-rw-r--r--bin/ed/test/Makefile26
-rw-r--r--bin/ed/test/README33
-rw-r--r--bin/ed/test/TODO18
-rw-r--r--bin/ed/test/a.d5
-rw-r--r--bin/ed/test/a.r8
-rw-r--r--bin/ed/test/a.t9
-rw-r--r--bin/ed/test/a1.err3
-rw-r--r--bin/ed/test/a2.err3
-rw-r--r--bin/ed/test/addr.d9
-rw-r--r--bin/ed/test/addr.r2
-rw-r--r--bin/ed/test/addr.t5
-rw-r--r--bin/ed/test/addr1.err1
-rw-r--r--bin/ed/test/addr2.err1
-rw-r--r--bin/ed/test/ascii.dbin0 -> 256 bytes
-rw-r--r--bin/ed/test/ascii.rbin0 -> 256 bytes
-rw-r--r--bin/ed/test/ascii.t0
-rw-r--r--bin/ed/test/bang1.d0
-rw-r--r--bin/ed/test/bang1.err1
-rw-r--r--bin/ed/test/bang1.r1
-rw-r--r--bin/ed/test/bang1.t5
-rw-r--r--bin/ed/test/bang2.err1
-rw-r--r--bin/ed/test/c.d5
-rw-r--r--bin/ed/test/c.r4
-rw-r--r--bin/ed/test/c.t12
-rw-r--r--bin/ed/test/c1.err3
-rw-r--r--bin/ed/test/c2.err3
-rw-r--r--bin/ed/test/ckscripts.sh38
-rw-r--r--bin/ed/test/d.d5
-rw-r--r--bin/ed/test/d.err1
-rw-r--r--bin/ed/test/d.r1
-rw-r--r--bin/ed/test/d.t3
-rw-r--r--bin/ed/test/e1.d1
-rw-r--r--bin/ed/test/e1.err1
-rw-r--r--bin/ed/test/e1.r1
-rw-r--r--bin/ed/test/e1.t1
-rw-r--r--bin/ed/test/e2.d1
-rw-r--r--bin/ed/test/e2.err1
-rw-r--r--bin/ed/test/e2.r1
-rw-r--r--bin/ed/test/e2.t1
-rw-r--r--bin/ed/test/e3.d1
-rw-r--r--bin/ed/test/e3.err1
-rw-r--r--bin/ed/test/e3.r1
-rw-r--r--bin/ed/test/e3.t1
-rw-r--r--bin/ed/test/e4.d1
-rw-r--r--bin/ed/test/e4.r1
-rw-r--r--bin/ed/test/e4.t1
-rw-r--r--bin/ed/test/f1.err1
-rw-r--r--bin/ed/test/f2.err1
-rw-r--r--bin/ed/test/g1.d5
-rw-r--r--bin/ed/test/g1.err1
-rw-r--r--bin/ed/test/g1.r15
-rw-r--r--bin/ed/test/g1.t6
-rw-r--r--bin/ed/test/g2.d5
-rw-r--r--bin/ed/test/g2.err1
-rw-r--r--bin/ed/test/g2.r1
-rw-r--r--bin/ed/test/g2.t2
-rw-r--r--bin/ed/test/g3.d5
-rw-r--r--bin/ed/test/g3.err1
-rw-r--r--bin/ed/test/g3.r5
-rw-r--r--bin/ed/test/g3.t4
-rw-r--r--bin/ed/test/g4.d5
-rw-r--r--bin/ed/test/g4.r7
-rw-r--r--bin/ed/test/g4.t13
-rw-r--r--bin/ed/test/g5.d3
-rw-r--r--bin/ed/test/g5.r9
-rw-r--r--bin/ed/test/g5.t2
-rw-r--r--bin/ed/test/h.err1
-rw-r--r--bin/ed/test/i.d5
-rw-r--r--bin/ed/test/i.r8
-rw-r--r--bin/ed/test/i.t9
-rw-r--r--bin/ed/test/i1.err3
-rw-r--r--bin/ed/test/i2.err3
-rw-r--r--bin/ed/test/i3.err3
-rw-r--r--bin/ed/test/j.d5
-rw-r--r--bin/ed/test/j.r4
-rw-r--r--bin/ed/test/j.t2
-rw-r--r--bin/ed/test/k.d5
-rw-r--r--bin/ed/test/k.r5
-rw-r--r--bin/ed/test/k.t10
-rw-r--r--bin/ed/test/k1.err1
-rw-r--r--bin/ed/test/k2.err1
-rw-r--r--bin/ed/test/k3.err1
-rw-r--r--bin/ed/test/k4.err6
-rw-r--r--bin/ed/test/l.d0
-rw-r--r--bin/ed/test/l.r0
-rw-r--r--bin/ed/test/l.t0
-rw-r--r--bin/ed/test/m.d5
-rw-r--r--bin/ed/test/m.err4
-rw-r--r--bin/ed/test/m.r5
-rw-r--r--bin/ed/test/m.t7
-rw-r--r--bin/ed/test/mkscripts.sh76
-rw-r--r--bin/ed/test/n.d0
-rw-r--r--bin/ed/test/n.r0
-rw-r--r--bin/ed/test/n.t0
-rw-r--r--bin/ed/test/nl.err1
-rw-r--r--bin/ed/test/nl1.d5
-rw-r--r--bin/ed/test/nl1.r8
-rw-r--r--bin/ed/test/nl1.t8
-rw-r--r--bin/ed/test/nl2.d5
-rw-r--r--bin/ed/test/nl2.r6
-rw-r--r--bin/ed/test/nl2.t4
-rw-r--r--bin/ed/test/p.d0
-rw-r--r--bin/ed/test/p.r0
-rw-r--r--bin/ed/test/p.t0
-rw-r--r--bin/ed/test/q.d0
-rw-r--r--bin/ed/test/q.r0
-rw-r--r--bin/ed/test/q.t5
-rw-r--r--bin/ed/test/q1.err1
-rw-r--r--bin/ed/test/r1.d5
-rw-r--r--bin/ed/test/r1.err1
-rw-r--r--bin/ed/test/r1.r7
-rw-r--r--bin/ed/test/r1.t3
-rw-r--r--bin/ed/test/r2.d5
-rw-r--r--bin/ed/test/r2.err1
-rw-r--r--bin/ed/test/r2.r10
-rw-r--r--bin/ed/test/r2.t1
-rw-r--r--bin/ed/test/r3.d1
-rw-r--r--bin/ed/test/r3.r2
-rw-r--r--bin/ed/test/r3.t1
-rw-r--r--bin/ed/test/s1.d5
-rw-r--r--bin/ed/test/s1.err1
-rw-r--r--bin/ed/test/s1.r5
-rw-r--r--bin/ed/test/s1.t6
-rw-r--r--bin/ed/test/s10.err4
-rw-r--r--bin/ed/test/s2.d5
-rw-r--r--bin/ed/test/s2.err4
-rw-r--r--bin/ed/test/s2.r5
-rw-r--r--bin/ed/test/s2.t4
-rw-r--r--bin/ed/test/s3.d0
-rw-r--r--bin/ed/test/s3.err1
-rw-r--r--bin/ed/test/s3.r1
-rw-r--r--bin/ed/test/s3.t6
-rw-r--r--bin/ed/test/s4.err1
-rw-r--r--bin/ed/test/s5.err1
-rw-r--r--bin/ed/test/s6.err1
-rw-r--r--bin/ed/test/s7.err5
-rw-r--r--bin/ed/test/s8.err4
-rw-r--r--bin/ed/test/s9.err4
-rw-r--r--bin/ed/test/t.d5
-rw-r--r--bin/ed/test/t.r16
-rw-r--r--bin/ed/test/t.t3
-rw-r--r--bin/ed/test/t1.d5
-rw-r--r--bin/ed/test/t1.err1
-rw-r--r--bin/ed/test/t1.r16
-rw-r--r--bin/ed/test/t1.t3
-rw-r--r--bin/ed/test/t2.d5
-rw-r--r--bin/ed/test/t2.err1
-rw-r--r--bin/ed/test/t2.r6
-rw-r--r--bin/ed/test/t2.t1
-rw-r--r--bin/ed/test/u.d5
-rw-r--r--bin/ed/test/u.err1
-rw-r--r--bin/ed/test/u.r9
-rw-r--r--bin/ed/test/u.t31
-rw-r--r--bin/ed/test/v.d5
-rw-r--r--bin/ed/test/v.r11
-rw-r--r--bin/ed/test/v.t6
-rw-r--r--bin/ed/test/w.d5
-rw-r--r--bin/ed/test/w.r10
-rw-r--r--bin/ed/test/w.t2
-rw-r--r--bin/ed/test/w1.err1
-rw-r--r--bin/ed/test/w2.err1
-rw-r--r--bin/ed/test/w3.err1
-rw-r--r--bin/ed/test/x.err1
-rw-r--r--bin/ed/test/z.err2
-rw-r--r--bin/ed/undo.c146
-rw-r--r--bin/expr/Makefile7
-rw-r--r--bin/expr/expr.1156
-rw-r--r--bin/expr/expr.c527
-rw-r--r--bin/hostname/Makefile5
-rw-r--r--bin/hostname/hostname.175
-rw-r--r--bin/hostname/hostname.c83
-rw-r--r--bin/kill/Makefile5
-rw-r--r--bin/kill/kill.1183
-rw-r--r--bin/kill/kill.c184
-rw-r--r--bin/ln/Makefile6
-rw-r--r--bin/ln/ln.1229
-rw-r--r--bin/ln/ln.c202
-rw-r--r--bin/ln/symlink.7463
-rw-r--r--bin/ls/Makefile9
-rw-r--r--bin/ls/cmp.c179
-rw-r--r--bin/ls/extern.h54
-rw-r--r--bin/ls/ls.1517
-rw-r--r--bin/ls/ls.c622
-rw-r--r--bin/ls/ls.h77
-rw-r--r--bin/ls/main.c13
-rw-r--r--bin/ls/print.c380
-rw-r--r--bin/ls/utf8.c57
-rw-r--r--bin/ls/util.c70
-rw-r--r--bin/md5/Makefile14
-rw-r--r--bin/md5/cksum.1191
-rw-r--r--bin/md5/crc.c137
-rw-r--r--bin/md5/crc.h31
-rw-r--r--bin/md5/md5.1145
-rw-r--r--bin/md5/md5.c828
-rw-r--r--bin/mkdir/Makefile5
-rw-r--r--bin/mkdir/mkdir.1121
-rw-r--r--bin/mkdir/mkdir.c178
-rw-r--r--bin/mv/Makefile6
-rw-r--r--bin/mv/cp.c677
-rw-r--r--bin/mv/mv.1197
-rw-r--r--bin/mv/mv.c382
-rw-r--r--bin/mv/pathnames.h36
-rw-r--r--bin/mv/rm.c267
-rw-r--r--bin/pax/Makefile10
-rw-r--r--bin/pax/ar_io.c1289
-rw-r--r--bin/pax/ar_subs.c1250
-rw-r--r--bin/pax/buf_subs.c982
-rw-r--r--bin/pax/cache.c424
-rw-r--r--bin/pax/cache.h73
-rw-r--r--bin/pax/cpio.1309
-rw-r--r--bin/pax/cpio.c1124
-rw-r--r--bin/pax/cpio.h150
-rw-r--r--bin/pax/extern.h323
-rw-r--r--bin/pax/file_subs.c1129
-rw-r--r--bin/pax/ftree.c554
-rw-r--r--bin/pax/ftree.h51
-rw-r--r--bin/pax/gen_subs.c394
-rw-r--r--bin/pax/getoldopt.c69
-rw-r--r--bin/pax/options.c1701
-rw-r--r--bin/pax/options.h113
-rw-r--r--bin/pax/pat_rep.c1096
-rw-r--r--bin/pax/pat_rep.h49
-rw-r--r--bin/pax/pax.11121
-rw-r--r--bin/pax/pax.c443
-rw-r--r--bin/pax/pax.h260
-rw-r--r--bin/pax/sel_subs.c602
-rw-r--r--bin/pax/sel_subs.h72
-rw-r--r--bin/pax/tables.c1656
-rw-r--r--bin/pax/tables.h165
-rw-r--r--bin/pax/tar.1401
-rw-r--r--bin/pax/tar.c1307
-rw-r--r--bin/pax/tar.h159
-rw-r--r--bin/pax/tty_subs.c189
-rw-r--r--bin/pwd/Makefile5
-rw-r--r--bin/pwd/pwd.1115
-rw-r--r--bin/pwd/pwd.c120
-rw-r--r--bin/rm/Makefile5
-rw-r--r--bin/rm/rm.1183
-rw-r--r--bin/rm/rm.c442
-rw-r--r--bin/rmdir/Makefile5
-rw-r--r--bin/rmdir/rmdir.1112
-rw-r--r--bin/rmdir/rmdir.c116
-rw-r--r--bin/sleep/Makefile5
-rw-r--r--bin/sleep/sleep.1112
-rw-r--r--bin/sleep/sleep.c134
-rw-r--r--bin/stty/Makefile6
-rw-r--r--bin/stty/cchar.c139
-rw-r--r--bin/stty/extern.h49
-rw-r--r--bin/stty/gfmt.c126
-rw-r--r--bin/stty/key.c363
-rw-r--r--bin/stty/modes.c252
-rw-r--r--bin/stty/print.c285
-rw-r--r--bin/stty/stty.1739
-rw-r--r--bin/stty/stty.c165
-rw-r--r--bin/stty/stty.h54
-rw-r--r--bin/sync/Makefile6
-rw-r--r--bin/sync/sync.872
-rw-r--r--bin/sync/sync.c40
-rw-r--r--bin/test/Makefile7
-rw-r--r--bin/test/test.1357
-rw-r--r--bin/test/test.c504
-rw-r--r--bsd.prog.mk78
-rw-r--r--configure.ac58
-rw-r--r--import.sh29
-rw-r--r--libopenbsd/Makefile82
-rw-r--r--libopenbsd/base64.c315
-rw-r--r--libopenbsd/chacha.h48
-rw-r--r--libopenbsd/closefrom.c107
-rw-r--r--libopenbsd/config.mk.in4
-rw-r--r--libopenbsd/crypt/.dirstamp0
-rw-r--r--libopenbsd/crypt/arc4random.c198
-rw-r--r--libopenbsd/crypt/arc4random.h2
-rw-r--r--libopenbsd/crypt/arc4random_linux.h88
-rw-r--r--libopenbsd/crypt/arc4random_uniform.c57
-rw-r--r--libopenbsd/crypt/chacha-merged.c270
-rw-r--r--libopenbsd/crypt/chacha.c77
-rw-r--r--libopenbsd/crypt/chacha_private.h222
-rw-r--r--libopenbsd/errc.c42
-rw-r--r--libopenbsd/execvpe.c157
-rw-r--r--libopenbsd/explicit_bzero.c21
-rw-r--r--libopenbsd/fgetln.c53
-rw-r--r--libopenbsd/fgetwln.3115
-rw-r--r--libopenbsd/fgetwln.c85
-rw-r--r--libopenbsd/fmt_scaled.3134
-rw-r--r--libopenbsd/fmt_scaled.c269
-rw-r--r--libopenbsd/fts.3780
-rw-r--r--libopenbsd/fts.c1048
-rw-r--r--libopenbsd/fts.h125
-rw-r--r--libopenbsd/getbsize.376
-rw-r--r--libopenbsd/getbsize.c101
-rw-r--r--libopenbsd/getentropy_linux.c547
-rwxr-xr-xlibopenbsd/getfsstatbin0 -> 11024 bytes
-rw-r--r--libopenbsd/getfsstat.2149
-rw-r--r--libopenbsd/getfsstat.c120
-rw-r--r--libopenbsd/getmntinfo.3102
-rw-r--r--libopenbsd/getmntinfo.c68
-rw-r--r--libopenbsd/hash/.dirstamp0
-rw-r--r--libopenbsd/hash/helper.c113
-rw-r--r--libopenbsd/hash/md5.3215
-rw-r--r--libopenbsd/hash/md5.c251
-rw-r--r--libopenbsd/hash/rmd160.3240
-rw-r--r--libopenbsd/hash/rmd160.c374
-rw-r--r--libopenbsd/hash/sha1.3243
-rw-r--r--libopenbsd/hash/sha1.c178
-rw-r--r--libopenbsd/hash/sha2.3328
-rw-r--r--libopenbsd/hash/sha2.c926
-rw-r--r--libopenbsd/heapsort.c173
-rw-r--r--libopenbsd/include/mpool.h122
-rw-r--r--libopenbsd/issetugid.c15
-rw-r--r--libopenbsd/libopenbsd.mk2
-rw-r--r--libopenbsd/logwtmp.c5
-rw-r--r--libopenbsd/md5.h49
-rw-r--r--libopenbsd/merge.c336
-rw-r--r--libopenbsd/mkfile84
-rw-r--r--libopenbsd/openbsd-queue.h533
-rw-r--r--libopenbsd/openbsd-tree.h748
-rw-r--r--libopenbsd/openbsd.h240
-rw-r--r--libopenbsd/pledge-noop.c7
-rw-r--r--libopenbsd/progname.c55
-rw-r--r--libopenbsd/pw_dup.380
-rw-r--r--libopenbsd/pw_dup.c87
-rw-r--r--libopenbsd/pwcache.387
-rw-r--r--libopenbsd/pwcache.c131
-rw-r--r--libopenbsd/qsort.c152
-rw-r--r--libopenbsd/radixsort.c294
-rw-r--r--libopenbsd/random.3194
-rw-r--r--libopenbsd/random.c419
-rw-r--r--libopenbsd/readpassphrase.c211
-rw-r--r--libopenbsd/readpassphrase.h37
-rw-r--r--libopenbsd/reallocarray.c38
-rw-r--r--libopenbsd/rmd160.h60
-rw-r--r--libopenbsd/setmode.3108
-rw-r--r--libopenbsd/setmode.c449
-rw-r--r--libopenbsd/setproctitle.394
-rw-r--r--libopenbsd/setproctitle.c36
-rw-r--r--libopenbsd/sha1.h57
-rw-r--r--libopenbsd/sha2.h136
-rw-r--r--libopenbsd/statfs.c7
-rw-r--r--libopenbsd/strlcat.c56
-rw-r--r--libopenbsd/strlcpy.c51
-rw-r--r--libopenbsd/strmode.3157
-rw-r--r--libopenbsd/strmode.c141
-rw-r--r--libopenbsd/strtod.3167
-rw-r--r--libopenbsd/strtoimax.c151
-rw-r--r--libopenbsd/strtonum.3152
-rw-r--r--libopenbsd/strtonum.c66
-rw-r--r--libopenbsd/strtoq.c11
-rw-r--r--libopenbsd/strtoumax.c109
-rw-r--r--libopenbsd/unvis.3195
-rw-r--r--libopenbsd/unvis.c286
-rw-r--r--libopenbsd/util.h2
-rw-r--r--libopenbsd/verrc.c47
-rw-r--r--libopenbsd/vis.3395
-rw-r--r--libopenbsd/vis.c243
-rw-r--r--libopenbsd/vis.h91
-rw-r--r--libopenbsd/vwarnc.c47
-rw-r--r--libopenbsd/warnc.c43
-rw-r--r--sbin/Makefile3
-rw-r--r--sbin/mknod/Makefile7
-rw-r--r--sbin/mknod/mkfifo.186
-rw-r--r--sbin/mknod/mknod.8143
-rw-r--r--sbin/mknod/mknod.c232
-rw-r--r--usr.bin/Makefile14
-rw-r--r--usr.bin/apply/Makefile6
-rw-r--r--usr.bin/apply/apply.1145
-rw-r--r--usr.bin/apply/apply.c248
-rw-r--r--usr.bin/awk/FIXES1011
-rw-r--r--usr.bin/awk/Makefile22
-rw-r--r--usr.bin/awk/README95
-rw-r--r--usr.bin/awk/USD.doc/Makefile13
-rw-r--r--usr.bin/awk/USD.doc/awk1467
-rw-r--r--usr.bin/awk/awk.1793
-rw-r--r--usr.bin/awk/awk.h240
-rw-r--r--usr.bin/awk/awkgram.y487
-rw-r--r--usr.bin/awk/b.c964
-rw-r--r--usr.bin/awk/lex.c597
-rw-r--r--usr.bin/awk/lib.c740
-rw-r--r--usr.bin/awk/main.c229
-rw-r--r--usr.bin/awk/maketab.c172
-rw-r--r--usr.bin/awk/parse.c277
-rw-r--r--usr.bin/awk/proto.h196
-rw-r--r--usr.bin/awk/run.c2023
-rw-r--r--usr.bin/awk/tran.c458
-rw-r--r--usr.bin/basename/Makefile5
-rw-r--r--usr.bin/basename/basename.176
-rw-r--r--usr.bin/basename/basename.c102
-rw-r--r--usr.bin/bc/Makefile17
-rw-r--r--usr.bin/bc/USD.doc/Makefile10
-rw-r--r--usr.bin/bc/USD.doc/bc1240
-rw-r--r--usr.bin/bc/bc.1403
-rw-r--r--usr.bin/bc/bc.library272
-rw-r--r--usr.bin/bc/bc.y1188
-rw-r--r--usr.bin/bc/extern.h48
-rw-r--r--usr.bin/bc/pathnames.h20
-rw-r--r--usr.bin/bc/scan.l363
-rw-r--r--usr.bin/bc/tty.c64
-rw-r--r--usr.bin/bc/y.tab.c3165
-rw-r--r--usr.bin/bc/y.tab.h173
-rw-r--r--usr.bin/biff/Makefile5
-rw-r--r--usr.bin/biff/biff.199
-rw-r--r--usr.bin/biff/biff.c97
-rw-r--r--usr.bin/cal/Makefile6
-rw-r--r--usr.bin/cal/README42
-rw-r--r--usr.bin/cal/cal.1132
-rw-r--r--usr.bin/cal/cal.c564
-rw-r--r--usr.bin/calendar/Makefile19
-rw-r--r--usr.bin/calendar/calendar.1271
-rw-r--r--usr.bin/calendar/calendar.c284
-rw-r--r--usr.bin/calendar/calendar.h128
-rw-r--r--usr.bin/calendar/calendars/calendar.all23
-rw-r--r--usr.bin/calendar/calendars/calendar.birthday361
-rw-r--r--usr.bin/calendar/calendars/calendar.canada40
-rw-r--r--usr.bin/calendar/calendars/calendar.christian29
-rw-r--r--usr.bin/calendar/calendars/calendar.computer83
-rw-r--r--usr.bin/calendar/calendars/calendar.croatian12
-rw-r--r--usr.bin/calendar/calendars/calendar.discord387
-rw-r--r--usr.bin/calendar/calendars/calendar.fictional57
-rw-r--r--usr.bin/calendar/calendars/calendar.french12
-rw-r--r--usr.bin/calendar/calendars/calendar.german12
-rw-r--r--usr.bin/calendar/calendars/calendar.history504
-rw-r--r--usr.bin/calendar/calendars/calendar.holiday579
-rw-r--r--usr.bin/calendar/calendars/calendar.judaic36
-rw-r--r--usr.bin/calendar/calendars/calendar.music537
-rw-r--r--usr.bin/calendar/calendars/calendar.nz48
-rw-r--r--usr.bin/calendar/calendars/calendar.openbsd122
-rw-r--r--usr.bin/calendar/calendars/calendar.pagan70
-rw-r--r--usr.bin/calendar/calendars/calendar.russian12
-rw-r--r--usr.bin/calendar/calendars/calendar.space55
-rw-r--r--usr.bin/calendar/calendars/calendar.uk44
-rw-r--r--usr.bin/calendar/calendars/calendar.ushistory209
-rw-r--r--usr.bin/calendar/calendars/calendar.usholiday41
-rw-r--r--usr.bin/calendar/calendars/calendar.world18
-rw-r--r--usr.bin/calendar/calendars/de_DE.UTF-8/calendar.all17
-rw-r--r--usr.bin/calendar/calendars/de_DE.UTF-8/calendar.feiertag42
-rw-r--r--usr.bin/calendar/calendars/de_DE.UTF-8/calendar.geschichte202
-rw-r--r--usr.bin/calendar/calendars/de_DE.UTF-8/calendar.kirche32
-rw-r--r--usr.bin/calendar/calendars/de_DE.UTF-8/calendar.literatur45
-rw-r--r--usr.bin/calendar/calendars/de_DE.UTF-8/calendar.musik57
-rw-r--r--usr.bin/calendar/calendars/de_DE.UTF-8/calendar.wissenschaft19
-rw-r--r--usr.bin/calendar/calendars/fr_FR.UTF-8/calendar.all14
-rw-r--r--usr.bin/calendar/calendars/fr_FR.UTF-8/calendar.fetes630
-rw-r--r--usr.bin/calendar/calendars/fr_FR.UTF-8/calendar.french12
-rw-r--r--usr.bin/calendar/calendars/fr_FR.UTF-8/calendar.jferies45
-rw-r--r--usr.bin/calendar/calendars/fr_FR.UTF-8/calendar.proverbes354
-rw-r--r--usr.bin/calendar/calendars/hr_HR.UTF-8/calendar.all12
-rw-r--r--usr.bin/calendar/calendars/hr_HR.UTF-8/calendar.praznici37
-rw-r--r--usr.bin/calendar/calendars/ru_RU.UTF-8/calendar.all16
-rw-r--r--usr.bin/calendar/calendars/ru_RU.UTF-8/calendar.common151
-rw-r--r--usr.bin/calendar/calendars/ru_RU.UTF-8/calendar.history282
-rw-r--r--usr.bin/calendar/calendars/ru_RU.UTF-8/calendar.orthodox60
-rw-r--r--usr.bin/calendar/calendars/ru_RU.UTF-8/calendar.pagan55
-rw-r--r--usr.bin/calendar/calendars/ru_RU.UTF-8/calendar.primety402
-rw-r--r--usr.bin/calendar/day.c706
-rw-r--r--usr.bin/calendar/io.c458
-rw-r--r--usr.bin/calendar/ostern.c76
-rw-r--r--usr.bin/calendar/paskha.c53
-rw-r--r--usr.bin/calendar/pathnames.h39
-rw-r--r--usr.bin/calendar/pesach.c65
-rw-r--r--usr.bin/cmp/Makefile6
-rw-r--r--usr.bin/cmp/cmp.1126
-rw-r--r--usr.bin/cmp/cmp.c157
-rw-r--r--usr.bin/cmp/extern.h43
-rw-r--r--usr.bin/cmp/misc.c56
-rw-r--r--usr.bin/cmp/regular.c103
-rw-r--r--usr.bin/cmp/special.c93
-rw-r--r--usr.bin/col/Makefile5
-rw-r--r--usr.bin/col/README50
-rw-r--r--usr.bin/col/col.1141
-rw-r--r--usr.bin/col/col.c547
-rw-r--r--usr.bin/colrm/Makefile5
-rw-r--r--usr.bin/colrm/colrm.1127
-rw-r--r--usr.bin/colrm/colrm.c189
-rw-r--r--usr.bin/column/Makefile5
-rw-r--r--usr.bin/column/column.1116
-rw-r--r--usr.bin/column/column.c362
-rw-r--r--usr.bin/comm/Makefile5
-rw-r--r--usr.bin/comm/comm.1114
-rw-r--r--usr.bin/comm/comm.c180
-rw-r--r--usr.bin/cut/Makefile5
-rw-r--r--usr.bin/cut/cut.1167
-rw-r--r--usr.bin/cut/cut.c330
-rw-r--r--usr.bin/dc/Makefile10
-rw-r--r--usr.bin/dc/USD.doc/Makefile13
-rw-r--r--usr.bin/dc/USD.doc/dc752
-rw-r--r--usr.bin/dc/bcode.c1746
-rw-r--r--usr.bin/dc/bcode.h97
-rw-r--r--usr.bin/dc/dc.1533
-rw-r--r--usr.bin/dc/dc.c125
-rw-r--r--usr.bin/dc/extern.h64
-rw-r--r--usr.bin/dc/inout.c411
-rw-r--r--usr.bin/dc/main.c34
-rw-r--r--usr.bin/dc/mem.c104
-rw-r--r--usr.bin/dc/stack.c353
-rw-r--r--usr.bin/diff/Makefile7
-rw-r--r--usr.bin/diff/diff.1477
-rw-r--r--usr.bin/diff/diff.c401
-rw-r--r--usr.bin/diff/diff.h98
-rw-r--r--usr.bin/diff/diffdir.c233
-rw-r--r--usr.bin/diff/diffreg.c1485
-rw-r--r--usr.bin/diff/xmalloc.c85
-rw-r--r--usr.bin/diff/xmalloc.h30
-rw-r--r--usr.bin/diff3/Makefile11
-rw-r--r--usr.bin/diff3/diff3.1201
-rw-r--r--usr.bin/diff3/diff3.ksh65
-rw-r--r--usr.bin/diff3/diff3prog.c616
-rw-r--r--usr.bin/dirname/Makefile5
-rw-r--r--usr.bin/dirname/dirname.194
-rw-r--r--usr.bin/dirname/dirname.c64
-rw-r--r--usr.bin/du/Makefile7
-rw-r--r--usr.bin/du/du.1239
-rw-r--r--usr.bin/du/du.c329
-rw-r--r--usr.bin/env/Makefile5
-rw-r--r--usr.bin/env/env.1127
-rw-r--r--usr.bin/env/env.c100
-rw-r--r--usr.bin/expand/Makefile5
-rw-r--r--usr.bin/expand/expand.1138
-rw-r--r--usr.bin/expand/expand.c171
-rw-r--r--usr.bin/false/Makefile6
-rw-r--r--usr.bin/false/false.162
-rw-r--r--usr.bin/false/false.c9
-rw-r--r--usr.bin/fmt/Makefile7
-rw-r--r--usr.bin/fmt/fmt.1190
-rw-r--r--usr.bin/fmt/fmt.c723
-rw-r--r--usr.bin/fold/Makefile6
-rw-r--r--usr.bin/fold/fold.1137
-rw-r--r--usr.bin/fold/fold.c273
-rw-r--r--usr.bin/getopt/Makefile5
-rw-r--r--usr.bin/getopt/getopt.1120
-rw-r--r--usr.bin/getopt/getopt.c42
-rw-r--r--usr.bin/grep/Makefile16
-rw-r--r--usr.bin/grep/binary.c95
-rw-r--r--usr.bin/grep/file.c227
-rw-r--r--usr.bin/grep/grep.1375
-rw-r--r--usr.bin/grep/grep.c510
-rw-r--r--usr.bin/grep/grep.h128
-rw-r--r--usr.bin/grep/mmfile.c101
-rw-r--r--usr.bin/grep/queue.c120
-rw-r--r--usr.bin/grep/util.c645
-rw-r--r--usr.bin/head/Makefile5
-rw-r--r--usr.bin/head/head.1111
-rw-r--r--usr.bin/head/head.c123
-rw-r--r--usr.bin/hexdump/Makefile8
-rw-r--r--usr.bin/hexdump/conv.c120
-rw-r--r--usr.bin/hexdump/display.c354
-rw-r--r--usr.bin/hexdump/hexdump.1381
-rw-r--r--usr.bin/hexdump/hexdump.c81
-rw-r--r--usr.bin/hexdump/hexdump.h94
-rw-r--r--usr.bin/hexdump/hexsyntax.c134
-rw-r--r--usr.bin/hexdump/od.1341
-rw-r--r--usr.bin/hexdump/odsyntax.c414
-rw-r--r--usr.bin/hexdump/parse.c535
-rw-r--r--usr.bin/id/Makefile9
-rw-r--r--usr.bin/id/groups.159
-rw-r--r--usr.bin/id/id.1158
-rw-r--r--usr.bin/id/id.c362
-rw-r--r--usr.bin/id/whoami.162
-rw-r--r--usr.bin/indent/Makefile6
-rw-r--r--usr.bin/indent/README97
-rw-r--r--usr.bin/indent/args.c313
-rw-r--r--usr.bin/indent/indent.1525
-rw-r--r--usr.bin/indent/indent.c1209
-rw-r--r--usr.bin/indent/indent_codes.h67
-rw-r--r--usr.bin/indent/indent_globs.h343
-rw-r--r--usr.bin/indent/io.c619
-rw-r--r--usr.bin/indent/lexi.c605
-rw-r--r--usr.bin/indent/parse.c322
-rw-r--r--usr.bin/indent/pr_comment.c415
-rw-r--r--usr.bin/join/Makefile6
-rw-r--r--usr.bin/join/join.1239
-rw-r--r--usr.bin/join/join.c651
-rw-r--r--usr.bin/jot/Makefile8
-rw-r--r--usr.bin/jot/jot.1282
-rw-r--r--usr.bin/jot/jot.c489
-rw-r--r--usr.bin/lam/Makefile5
-rw-r--r--usr.bin/lam/lam.1131
-rw-r--r--usr.bin/lam/lam.c234
-rw-r--r--usr.bin/lndir/Makefile5
-rw-r--r--usr.bin/lndir/lndir.1206
-rw-r--r--usr.bin/lndir/lndir.c326
-rw-r--r--usr.bin/logger/Makefile5
-rw-r--r--usr.bin/logger/logger.1106
-rw-r--r--usr.bin/logger/logger.c185
-rw-r--r--usr.bin/logname/Makefile5
-rw-r--r--usr.bin/logname/logname.175
-rw-r--r--usr.bin/logname/logname.c76
-rw-r--r--usr.bin/look/Makefile5
-rw-r--r--usr.bin/look/look.1106
-rw-r--r--usr.bin/look/look.c317
-rw-r--r--usr.bin/look/pathnames.h35
-rw-r--r--usr.bin/mktemp/Makefile6
-rw-r--r--usr.bin/mktemp/mktemp.1264
-rw-r--r--usr.bin/mktemp/mktemp.c158
-rw-r--r--usr.bin/nice/Makefile5
-rw-r--r--usr.bin/nice/nice.1111
-rw-r--r--usr.bin/nice/nice.c108
-rw-r--r--usr.bin/nl/Makefile6
-rw-r--r--usr.bin/nl/nl.1220
-rw-r--r--usr.bin/nl/nl.c366
-rw-r--r--usr.bin/nohup/Makefile5
-rw-r--r--usr.bin/nohup/nohup.1122
-rw-r--r--usr.bin/nohup/nohup.c137
-rw-r--r--usr.bin/paste/Makefile5
-rw-r--r--usr.bin/paste/paste.1145
-rw-r--r--usr.bin/paste/paste.c261
-rw-r--r--usr.bin/patch/Makefile7
-rw-r--r--usr.bin/patch/backupfile.c236
-rw-r--r--usr.bin/patch/backupfile.h38
-rw-r--r--usr.bin/patch/common.h110
-rw-r--r--usr.bin/patch/ed.c339
-rw-r--r--usr.bin/patch/ed.h19
-rw-r--r--usr.bin/patch/inp.c433
-rw-r--r--usr.bin/patch/inp.h31
-rw-r--r--usr.bin/patch/mkpath.c77
-rw-r--r--usr.bin/patch/patch.1686
-rw-r--r--usr.bin/patch/patch.c1060
-rw-r--r--usr.bin/patch/pathnames.h11
-rw-r--r--usr.bin/patch/pch.c1507
-rw-r--r--usr.bin/patch/pch.h61
-rw-r--r--usr.bin/patch/util.c411
-rw-r--r--usr.bin/patch/util.h50
-rw-r--r--usr.bin/printenv/Makefile5
-rw-r--r--usr.bin/printenv/printenv.168
-rw-r--r--usr.bin/printenv/printenv.c69
-rw-r--r--usr.bin/printf/Makefile5
-rw-r--r--usr.bin/printf/printf.1395
-rw-r--r--usr.bin/printf/printf.c505
-rw-r--r--usr.bin/readlink/Makefile5
-rw-r--r--usr.bin/readlink/readlink.179
-rw-r--r--usr.bin/readlink/readlink.c95
-rw-r--r--usr.bin/renice/Makefile6
-rw-r--r--usr.bin/renice/renice.8144
-rw-r--r--usr.bin/renice/renice.c188
-rw-r--r--usr.bin/rev/Makefile5
-rw-r--r--usr.bin/rev/rev.149
-rw-r--r--usr.bin/rev/rev.c117
-rw-r--r--usr.bin/rs/Makefile7
-rw-r--r--usr.bin/rs/rs.1254
-rw-r--r--usr.bin/rs/rs.c473
-rw-r--r--usr.bin/rs/utf8.c61
-rw-r--r--usr.bin/sed/Makefile6
-rw-r--r--usr.bin/sed/POSIX199
-rw-r--r--usr.bin/sed/TEST/hanoi.sed103
-rw-r--r--usr.bin/sed/TEST/math.sed164
-rw-r--r--usr.bin/sed/TEST/sed.test549
-rw-r--r--usr.bin/sed/USD.doc/Makefile10
-rw-r--r--usr.bin/sed/USD.doc/sed1125
-rw-r--r--usr.bin/sed/compile.c862
-rw-r--r--usr.bin/sed/defs.h147
-rw-r--r--usr.bin/sed/extern.h59
-rw-r--r--usr.bin/sed/main.c499
-rw-r--r--usr.bin/sed/misc.c123
-rw-r--r--usr.bin/sed/process.c639
-rw-r--r--usr.bin/sed/sed.1589
-rw-r--r--usr.bin/shar/Makefile9
-rw-r--r--usr.bin/shar/shar.1102
-rw-r--r--usr.bin/shar/shar.sh73
-rw-r--r--usr.bin/sort/Makefile8
-rw-r--r--usr.bin/sort/bwstring.c1133
-rw-r--r--usr.bin/sort/bwstring.h140
-rw-r--r--usr.bin/sort/coll.c1283
-rw-r--r--usr.bin/sort/coll.h158
-rw-r--r--usr.bin/sort/file.c1135
-rw-r--r--usr.bin/sort/file.h123
-rw-r--r--usr.bin/sort/mem.c105
-rw-r--r--usr.bin/sort/mem.h48
-rw-r--r--usr.bin/sort/radixsort.c459
-rw-r--r--usr.bin/sort/radixsort.h38
-rw-r--r--usr.bin/sort/sort.1641
-rw-r--r--usr.bin/sort/sort.c1246
-rw-r--r--usr.bin/sort/sort.h108
-rw-r--r--usr.bin/sort/test.c1
-rw-r--r--usr.bin/sort/vsort.c260
-rw-r--r--usr.bin/sort/vsort.h37
-rw-r--r--usr.bin/split/Makefile5
-rw-r--r--usr.bin/split/split.1153
-rw-r--r--usr.bin/split/split.c321
-rw-r--r--usr.bin/stat/Makefile7
-rw-r--r--usr.bin/stat/stat.1488
-rw-r--r--usr.bin/stat/stat.c1027
-rw-r--r--usr.bin/tee/Makefile5
-rw-r--r--usr.bin/tee/tee.184
-rw-r--r--usr.bin/tee/tee.c141
-rw-r--r--usr.bin/time/Makefile5
-rw-r--r--usr.bin/time/time.1128
-rw-r--r--usr.bin/time/time.c194
-rw-r--r--usr.bin/touch/Makefile6
-rw-r--r--usr.bin/touch/touch.1183
-rw-r--r--usr.bin/touch/touch.c334
-rw-r--r--usr.bin/tr/Makefile6
-rw-r--r--usr.bin/tr/extern.h49
-rw-r--r--usr.bin/tr/str.c323
-rw-r--r--usr.bin/tr/tr.1364
-rw-r--r--usr.bin/tr/tr.c251
-rw-r--r--usr.bin/true/Makefile6
-rw-r--r--usr.bin/true/true.163
-rw-r--r--usr.bin/true/true.c9
-rw-r--r--usr.bin/tty/Makefile5
-rw-r--r--usr.bin/tty/tty.188
-rw-r--r--usr.bin/tty/tty.c73
-rw-r--r--usr.bin/uname/Makefile5
-rw-r--r--usr.bin/uname/uname.194
-rw-r--r--usr.bin/uname/uname.c155
-rw-r--r--usr.bin/unexpand/Makefile6
-rw-r--r--usr.bin/unexpand/unexpand.c141
-rw-r--r--usr.bin/uniq/Makefile7
-rw-r--r--usr.bin/uniq/uniq.1148
-rw-r--r--usr.bin/uniq/uniq.c263
-rw-r--r--usr.bin/unvis/Makefile5
-rw-r--r--usr.bin/unvis/unvis.156
-rw-r--r--usr.bin/unvis/unvis.c108
-rw-r--r--usr.bin/uudecode/Makefile7
-rw-r--r--usr.bin/uudecode/uudecode.c461
-rw-r--r--usr.bin/uuencode/Makefile7
-rw-r--r--usr.bin/uuencode/uuencode.1238
-rw-r--r--usr.bin/uuencode/uuencode.599
-rw-r--r--usr.bin/uuencode/uuencode.c237
-rw-r--r--usr.bin/vis/Makefile6
-rw-r--r--usr.bin/vis/foldit.c71
-rw-r--r--usr.bin/vis/vis.1138
-rw-r--r--usr.bin/vis/vis.c187
-rw-r--r--usr.bin/wc/Makefile7
-rw-r--r--usr.bin/wc/wc.1138
-rw-r--r--usr.bin/wc/wc.c294
-rw-r--r--usr.bin/what/Makefile5
-rw-r--r--usr.bin/what/what.1107
-rw-r--r--usr.bin/what/what.c142
-rw-r--r--usr.bin/which/Makefile19
-rw-r--r--usr.bin/which/whereis.194
-rw-r--r--usr.bin/which/which.1101
-rw-r--r--usr.bin/which/which.c160
-rw-r--r--usr.bin/xinstall/Makefile12
-rw-r--r--usr.bin/xinstall/install.1229
-rw-r--r--usr.bin/xinstall/pathnames.h36
-rw-r--r--usr.bin/xinstall/xinstall.c841
-rw-r--r--usr.sbin/Makefile2
-rw-r--r--usr.sbin/mtree/Makefile8
-rw-r--r--usr.sbin/mtree/compare.c412
-rw-r--r--usr.sbin/mtree/crc.c135
-rw-r--r--usr.sbin/mtree/create.c385
-rw-r--r--usr.sbin/mtree/extern.h48
-rw-r--r--usr.sbin/mtree/misc.c116
-rw-r--r--usr.sbin/mtree/mtree.8352
-rw-r--r--usr.sbin/mtree/mtree.c185
-rw-r--r--usr.sbin/mtree/mtree.h103
-rw-r--r--usr.sbin/mtree/spec.c322
-rw-r--r--usr.sbin/mtree/verify.c212
-rw-r--r--usr.sbin/rdate/Makefile11
-rw-r--r--usr.sbin/rdate/ntp.c487
-rw-r--r--usr.sbin/rdate/ntpleaps.c195
-rw-r--r--usr.sbin/rdate/ntpleaps.h73
-rw-r--r--usr.sbin/rdate/rdate.8112
-rw-r--r--usr.sbin/rdate/rdate.c228
-rw-r--r--usr.sbin/rdate/rfc868time.c121
832 files changed, 150647 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..da10748
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.[ao]
+config.mk
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..7f0fa5b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,15 @@
+SUBDIRS = libopenbsd bin sbin usr.bin usr.sbin
+
+all:
+
+clean:
+ PATH=$$PWD/dest/bin/:$$PATH $(MAKE) -I$(SRCDIR) -C regress clean
+
+check:
+ PATH=$$PWD/dest/bin/:$$PATH $(MAKE) -I$(SRCDIR) -C regress SRCDIR=$(SRCDIR) SHELL=/bin/oksh
+
+insteall:
+
+include mk/subdirs.mk
+
+.PHONY: all clean check install
diff --git a/OPENBSD_BRANCH b/OPENBSD_BRANCH
new file mode 100644
index 0000000..22b1829
--- /dev/null
+++ b/OPENBSD_BRANCH
@@ -0,0 +1 @@
+OPENBSD_6_0
diff --git a/bin/Makefile b/bin/Makefile
new file mode 100644
index 0000000..97b349c
--- /dev/null
+++ b/bin/Makefile
@@ -0,0 +1,12 @@
+SUBDIRS = cat chmod cp date dd df domainname echo ed expr hostname kill ln ls \
+ md5 mkdir mv pax pwd rm rmdir sleep stty sync test
+
+BROKEN = df
+
+all:
+
+include ../mk/subdirs.mk
+
+$(BROKEN):
+ @echo "skipping $@"
+ @true
diff --git a/bin/cat/CVS/Entries b/bin/cat/CVS/Entries
new file mode 100644
index 0000000..89835cd
--- /dev/null
+++ b/bin/cat/CVS/Entries
@@ -0,0 +1,4 @@
+/cat.1/1.36/Sun Aug 7 17:13:44 2016//
+/Makefile/1.4/Wed Feb 22 00:56:59 2017//
+/cat.c/1.26/Wed Feb 22 00:56:59 2017//
+D
diff --git a/bin/cat/CVS/Repository b/bin/cat/CVS/Repository
new file mode 100644
index 0000000..3626f7a
--- /dev/null
+++ b/bin/cat/CVS/Repository
@@ -0,0 +1 @@
+src/bin/cat
diff --git a/bin/cat/CVS/Root b/bin/cat/CVS/Root
new file mode 100644
index 0000000..f9802fd
--- /dev/null
+++ b/bin/cat/CVS/Root
@@ -0,0 +1 @@
+anoncvs@ftp.hostserver.de:/cvs
diff --git a/bin/cat/Makefile b/bin/cat/Makefile
new file mode 100644
index 0000000..44a515f
--- /dev/null
+++ b/bin/cat/Makefile
@@ -0,0 +1,6 @@
+# $OpenBSD: Makefile,v 1.4 2017/02/19 00:46:57 jca Exp $
+
+PROG= cat
+
+
+include bsd.prog.mk
diff --git a/bin/cat/Makefile,v b/bin/cat/Makefile,v
new file mode 100644
index 0000000..aee8235
--- /dev/null
+++ b/bin/cat/Makefile,v
@@ -0,0 +1,180 @@
+head 1.4;
+access;
+symbols
+ OPENBSD_2_0:1.2.0.2
+ OPENBSD_2_0_BASE:1.2
+ OPENBSD_2_1:1.2.0.4
+ OPENBSD_2_1_BASE:1.2
+ OPENBSD_2_2:1.3.0.2
+ OPENBSD_2_2_BASE:1.3
+ OPENBSD_2_3:1.3.0.4
+ OPENBSD_2_3_BASE:1.3
+ OPENBSD_2_4:1.3.0.6
+ OPENBSD_2_4_BASE:1.3
+ OPENBSD_2_5:1.3.0.8
+ OPENBSD_2_5_BASE:1.3
+ OPENBSD_2_6:1.3.0.10
+ OPENBSD_2_6_BASE:1.3
+ OPENBSD_2_7:1.3.0.12
+ OPENBSD_2_7_BASE:1.3
+ OPENBSD_2_8:1.3.0.14
+ OPENBSD_2_8_BASE:1.3
+ OPENBSD_2_9:1.3.0.16
+ OPENBSD_2_9_BASE:1.3
+ OPENBSD_3_0:1.3.0.18
+ OPENBSD_3_0_BASE:1.3
+ OPENBSD_3_1:1.3.0.20
+ OPENBSD_3_1_BASE:1.3
+ OPENBSD_3_2:1.3.0.22
+ OPENBSD_3_2_BASE:1.3
+ OPENBSD_3_3:1.3.0.24
+ OPENBSD_3_3_BASE:1.3
+ OPENBSD_3_4:1.3.0.26
+ OPENBSD_3_4_BASE:1.3
+ OPENBSD_3_5:1.3.0.28
+ OPENBSD_3_5_BASE:1.3
+ OPENBSD_3_6:1.3.0.30
+ OPENBSD_3_6_BASE:1.3
+ OPENBSD_3_7:1.3.0.32
+ OPENBSD_3_7_BASE:1.3
+ OPENBSD_3_8:1.3.0.34
+ OPENBSD_3_8_BASE:1.3
+ OPENBSD_3_9:1.3.0.36
+ OPENBSD_3_9_BASE:1.3
+ OPENBSD_4_0:1.3.0.38
+ OPENBSD_4_0_BASE:1.3
+ OPENBSD_4_1:1.3.0.40
+ OPENBSD_4_1_BASE:1.3
+ OPENBSD_4_2:1.3.0.42
+ OPENBSD_4_2_BASE:1.3
+ OPENBSD_4_3:1.3.0.44
+ OPENBSD_4_3_BASE:1.3
+ OPENBSD_4_4:1.3.0.46
+ OPENBSD_4_4_BASE:1.3
+ OPENBSD_4_5:1.3.0.48
+ OPENBSD_4_5_BASE:1.3
+ OPENBSD_4_6:1.3.0.52
+ OPENBSD_4_6_BASE:1.3
+ OPENBSD_4_7:1.3.0.50
+ OPENBSD_4_7_BASE:1.3
+ OPENBSD_4_8:1.3.0.54
+ OPENBSD_4_8_BASE:1.3
+ OPENBSD_4_9:1.3.0.56
+ OPENBSD_4_9_BASE:1.3
+ OPENBSD_5_0:1.3.0.58
+ OPENBSD_5_0_BASE:1.3
+ OPENBSD_5_1:1.3.0.60
+ OPENBSD_5_1_BASE:1.3
+ OPENBSD_5_2:1.3.0.62
+ OPENBSD_5_2_BASE:1.3
+ OPENBSD_5_3:1.3.0.64
+ OPENBSD_5_3_BASE:1.3
+ OPENBSD_5_4:1.3.0.66
+ OPENBSD_5_4_BASE:1.3
+ OPENBSD_5_5:1.3.0.70
+ OPENBSD_5_5_BASE:1.3
+ OPENBSD_5_6:1.3.0.72
+ OPENBSD_5_6_BASE:1.3
+ OPENBSD_5_7:1.3.0.68
+ OPENBSD_5_7_BASE:1.3
+ OPENBSD_5_8:1.3.0.76
+ OPENBSD_5_8_BASE:1.3
+ OPENBSD_5_9:1.3.0.74
+ OPENBSD_5_9_BASE:1.3
+ OPENBSD_6_0:1.3.0.78
+ OPENBSD_6_0_BASE:1.3
+ netbsd_1_1:1.1.1.1;
+locks; strict;
+comment @# @;
+
+
+1.4
+date 2017.02.19.00.46.57; author jca; state Exp;
+branches;
+next 1.3;
+commitid s7hTvhg95CVaKEjc;
+
+1.3
+date 97.09.21.11.34.39; author deraadt; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 96.06.23.14.19.01; author deraadt; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 95.10.18.08.37.01; author deraadt; state Exp;
+branches
+ 1.1.1.1;
+next ;
+
+1.1.1.1
+date 95.10.18.08.37.01; author deraadt; state Exp;
+branches;
+next ;
+
+
+
+desc
+@@
+
+
+1.4
+log
+@More whitespace, helps reading
+
+ok ajacoutot@@
+@
+text
+@# $OpenBSD: Makefile,v 1.3 1997/09/21 11:34:39 deraadt Exp $
+
+PROG= cat
+
+
+.include <bsd.prog.mk>
+@
+
+
+1.3
+log
+@$OpenBSD$
+@
+text
+@d1 1
+a1 1
+# $OpenBSD: Makefile,v 1.2 1996/06/23 14:19:01 deraadt Exp $
+d4 1
+@
+
+
+1.2
+log
+@update rcsid
+@
+text
+@d1 1
+a1 2
+# $OpenBSD: Makefile,v 1.6 1995/04/23 10:07:18 cgd Exp $
+# $NetBSD: Makefile,v 1.6 1995/04/23 10:07:18 cgd Exp $
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d1 1
+a2 1
+# @@(#)Makefile 8.1 (Berkeley) 5/31/93
+@
+
+
+1.1.1.1
+log
+@initial import of NetBSD tree
+@
+text
+@@
diff --git a/bin/cat/cat.1 b/bin/cat/cat.1
new file mode 100644
index 0000000..e582167
--- /dev/null
+++ b/bin/cat/cat.1
@@ -0,0 +1,185 @@
+.\" $OpenBSD: cat.1,v 1.36 2016/07/10 00:15:39 tedu Exp $
+.\" $NetBSD: cat.1,v 1.12 1995/09/27 05:38:55 cgd Exp $
+.\"
+.\" Copyright (c) 1989, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the Institute of Electrical and Electronics Engineers, Inc.
+.\"
+.\" 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. 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.
+.\"
+.\" @(#)cat.1 8.3 (Berkeley) 5/2/95
+.\"
+.Dd $Mdocdate: July 10 2016 $
+.Dt CAT 1
+.Os
+.Sh NAME
+.Nm cat
+.Nd concatenate and print files
+.Sh SYNOPSIS
+.Nm cat
+.Op Fl benstuv
+.Op Ar
+.Sh DESCRIPTION
+The
+.Nm
+utility reads files sequentially, writing them to the standard output.
+The
+.Ar file
+operands are processed in command-line order.
+If
+.Ar file
+is a single dash
+.Pq Sq -
+or absent,
+.Nm
+reads from the standard input.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl b
+Number the lines, but don't count blank lines.
+.It Fl e
+Print a dollar sign
+.Pq Ql \&$
+at the end of each line.
+Implies the
+.Fl v
+option to display non-printing characters.
+.It Fl n
+Number the output lines, starting at 1.
+.It Fl s
+Squeeze multiple adjacent empty lines, causing the output to be
+single spaced.
+.It Fl t
+Print tab characters as
+.Ql ^I .
+Implies the
+.Fl v
+option to display non-printing characters.
+.It Fl u
+The output is guaranteed to be unbuffered (see
+.Xr setvbuf 3 ) .
+.It Fl v
+Displays non-printing characters so they are visible.
+Control characters print as
+.Ql ^X
+for control-X, with the exception of the tab and EOL characters,
+which are displayed normally.
+The DEL character (octal 0177) prints as
+.Ql ^? .
+Non-ASCII characters (with the high bit set) are printed as
+.Ql M-
+(for meta) followed by the character for the low 7 bits.
+.El
+.Sh EXIT STATUS
+.Ex -std cat
+.Sh EXAMPLES
+Print the contents of
+.Ar file1
+to the standard output:
+.Pp
+.Dl $ cat file1
+.Pp
+Sequentially print the contents of
+.Ar file1
+and
+.Ar file2
+to the file
+.Ar file3 ,
+truncating
+.Ar file3
+if it already exists.
+See the manual page for your shell (e.g.,
+.Xr sh 1 )
+for more information on redirection.
+.Pp
+.Dl $ cat file1 file2 > file3
+.Pp
+Print the contents of
+.Ar file1 ,
+print data it receives from the standard input until it receives an
+.Dv EOF
+.Pq Sq ^D
+character, print the contents of
+.Ar file2 ,
+read and output contents of the standard input again, then finally output
+the contents of
+.Ar file3 .
+Note that if the standard input referred to a file, the second dash
+on the command line would have no effect, since the entire contents of the file
+would have already been read and printed by
+.Nm
+when it encountered the first
+.Ql \&-
+operand.
+.Pp
+.Dl $ cat file1 - file2 - file3
+.Sh SEE ALSO
+.Xr head 1 ,
+.Xr less 1 ,
+.Xr more 1 ,
+.Xr pr 1 ,
+.Xr sh 1 ,
+.Xr tail 1 ,
+.Xr vis 1 ,
+.Xr setvbuf 3
+.Rs
+.%A Rob Pike
+.%T "UNIX Style, or cat -v Considered Harmful"
+.%J "USENIX Summer Conference Proceedings"
+.%D 1983
+.Re
+.Sh STANDARDS
+The
+.Nm
+utility is compliant with the
+.St -p1003.1-2008
+specification.
+.Pp
+The flags
+.Op Fl benstv
+are extensions to that specification.
+.Sh HISTORY
+A
+.Nm
+utility appeared in
+.At v1 .
+.Sh CAVEATS
+Because of the shell language mechanism used to perform output
+redirection, the following command will cause the original data in
+.Ar file1
+to be destroyed:
+.Pp
+.Dl $ cat file1 file2 > file1
+.Pp
+To append
+.Ar file2
+to
+.Ar file1 ,
+instead use:
+.Pp
+.Dl $ cat file2 >> file1
diff --git a/bin/cat/cat.c b/bin/cat/cat.c
new file mode 100644
index 0000000..ed28a7f
--- /dev/null
+++ b/bin/cat/cat.c
@@ -0,0 +1,249 @@
+/* $OpenBSD: cat.c,v 1.26 2016/10/19 18:20:25 schwarze Exp $ */
+/* $NetBSD: cat.c,v 1.11 1995/09/07 06:12:54 jtc Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Kevin Fall.
+ *
+ * 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. 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.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b))
+
+extern char *__progname;
+
+int bflag, eflag, nflag, sflag, tflag, vflag;
+int rval;
+char *filename;
+
+void cook_args(char *argv[]);
+void cook_buf(FILE *);
+void raw_args(char *argv[]);
+void raw_cat(int);
+
+int
+main(int argc, char *argv[])
+{
+ int ch;
+
+ if (pledge("stdio rpath", NULL) == -1)
+ err(1, "pledge");
+
+ while ((ch = getopt(argc, argv, "benstuv")) != -1)
+ switch (ch) {
+ case 'b':
+ bflag = nflag = 1; /* -b implies -n */
+ break;
+ case 'e':
+ eflag = vflag = 1; /* -e implies -v */
+ break;
+ case 'n':
+ nflag = 1;
+ break;
+ case 's':
+ sflag = 1;
+ break;
+ case 't':
+ tflag = vflag = 1; /* -t implies -v */
+ break;
+ case 'u':
+ setvbuf(stdout, NULL, _IONBF, 0);
+ break;
+ case 'v':
+ vflag = 1;
+ break;
+ default:
+ (void)fprintf(stderr,
+ "usage: %s [-benstuv] [file ...]\n", __progname);
+ return 1;
+ }
+ argv += optind;
+
+ if (bflag || eflag || nflag || sflag || tflag || vflag)
+ cook_args(argv);
+ else
+ raw_args(argv);
+ if (fclose(stdout))
+ err(1, "stdout");
+ return rval;
+}
+
+void
+cook_args(char **argv)
+{
+ FILE *fp;
+
+ fp = stdin;
+ filename = "stdin";
+ do {
+ if (*argv) {
+ if (!strcmp(*argv, "-"))
+ fp = stdin;
+ else if ((fp = fopen(*argv, "r")) == NULL) {
+ warn("%s", *argv);
+ rval = 1;
+ ++argv;
+ continue;
+ }
+ filename = *argv++;
+ }
+ cook_buf(fp);
+ if (fp == stdin)
+ clearerr(fp);
+ else
+ (void)fclose(fp);
+ } while (*argv);
+}
+
+void
+cook_buf(FILE *fp)
+{
+ int ch, gobble, line, prev;
+
+ line = gobble = 0;
+ for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
+ if (prev == '\n') {
+ if (sflag) {
+ if (ch == '\n') {
+ if (gobble)
+ continue;
+ gobble = 1;
+ } else
+ gobble = 0;
+ }
+ if (nflag) {
+ if (!bflag || ch != '\n') {
+ (void)fprintf(stdout, "%6d\t", ++line);
+ if (ferror(stdout))
+ break;
+ } else if (eflag) {
+ (void)fprintf(stdout, "%6s\t", "");
+ if (ferror(stdout))
+ break;
+ }
+ }
+ }
+ if (ch == '\n') {
+ if (eflag && putchar('$') == EOF)
+ break;
+ } else if (ch == '\t') {
+ if (tflag) {
+ if (putchar('^') == EOF || putchar('I') == EOF)
+ break;
+ continue;
+ }
+ } else if (vflag) {
+ if (!isascii(ch)) {
+ if (putchar('M') == EOF || putchar('-') == EOF)
+ break;
+ ch = toascii(ch);
+ }
+ if (iscntrl(ch)) {
+ if (putchar('^') == EOF ||
+ putchar(ch == '\177' ? '?' :
+ ch | 0100) == EOF)
+ break;
+ continue;
+ }
+ }
+ if (putchar(ch) == EOF)
+ break;
+ }
+ if (ferror(fp)) {
+ warn("%s", filename);
+ rval = 1;
+ clearerr(fp);
+ }
+ if (ferror(stdout))
+ err(1, "stdout");
+}
+
+void
+raw_args(char **argv)
+{
+ int fd;
+
+ fd = fileno(stdin);
+ filename = "stdin";
+ do {
+ if (*argv) {
+ if (!strcmp(*argv, "-"))
+ fd = fileno(stdin);
+ else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
+ warn("%s", *argv);
+ rval = 1;
+ ++argv;
+ continue;
+ }
+ filename = *argv++;
+ }
+ raw_cat(fd);
+ if (fd != fileno(stdin))
+ (void)close(fd);
+ } while (*argv);
+}
+
+void
+raw_cat(int rfd)
+{
+ int wfd;
+ ssize_t nr, nw, off;
+ static size_t bsize;
+ static char *buf = NULL;
+ struct stat sbuf;
+
+ wfd = fileno(stdout);
+ if (buf == NULL) {
+ if (fstat(wfd, &sbuf))
+ err(1, "stdout");
+ bsize = MAXIMUM(sbuf.st_blksize, BUFSIZ);
+ if ((buf = malloc(bsize)) == NULL)
+ err(1, "malloc");
+ }
+ while ((nr = read(rfd, buf, bsize)) != -1 && nr != 0)
+ for (off = 0; nr; nr -= nw, off += nw)
+ if ((nw = write(wfd, buf + off, (size_t)nr)) == 0 ||
+ nw == -1)
+ err(1, "stdout");
+ if (nr < 0) {
+ warn("%s", filename);
+ rval = 1;
+ }
+}
diff --git a/bin/chmod/Makefile b/bin/chmod/Makefile
new file mode 100644
index 0000000..e39cc1d
--- /dev/null
+++ b/bin/chmod/Makefile
@@ -0,0 +1,18 @@
+# $OpenBSD: Makefile,v 1.7 2001/09/06 18:52:55 mickey Exp $
+
+PROG= chmod
+CFLAGS+=-DSUPPORT_DOT
+MAN= chmod.1 chgrp.1 chown.8 chflags.1
+LINKS= ${BINDIR}/chmod ${BINDIR}/chgrp \
+ ${BINDIR}/chmod /sbin/chown
+
+# XXX compatibility
+#afterinstall:
+# (cd ${DESTDIR}/usr/sbin; \
+# ln -sf ../../sbin/chown .; \
+# ln -sf ../../bin/chgrp .)
+# (cd ${DESTDIR}/usr/bin; \
+# ln -sf ../../bin/chmod chflags)
+
+
+include bsd.prog.mk
diff --git a/bin/chmod/chflags.1 b/bin/chmod/chflags.1
new file mode 100644
index 0000000..a146078
--- /dev/null
+++ b/bin/chmod/chflags.1
@@ -0,0 +1,174 @@
+.\" $OpenBSD: chflags.1,v 1.16 2015/12/31 23:38:16 guenther Exp $
+.\" $NetBSD: chflags.1,v 1.4 1995/08/31 22:50:22 jtc Exp $
+.\"
+.\" Copyright (c) 1989, 1990, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the Institute of Electrical and Electronics Engineers, Inc.
+.\"
+.\" 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. 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.
+.\"
+.\" @(#)chflags.1 8.4 (Berkeley) 5/2/95
+.\"
+.Dd $Mdocdate: December 31 2015 $
+.Dt CHFLAGS 1
+.Os
+.Sh NAME
+.Nm chflags
+.Nd change file flags
+.Sh SYNOPSIS
+.Nm chflags
+.Op Fl h
+.Oo
+.Fl R
+.Op Fl H | L | P
+.Oc
+.Ar flags
+.Ar
+.Sh DESCRIPTION
+The
+.Nm
+utility modifies the file flags of the listed files
+as specified by the
+.Ar flags
+operand.
+The
+.Ar flags
+of a file dictate special restrictions beyond those enforced by its
+mode/permissions.
+Only the superuser can change the user flags on block and
+character devices.
+.Pp
+You can use
+.Ic ls -lo
+to see the flags of existing files.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl H
+If the
+.Fl R
+option is also specified, symbolic links on the command line are followed.
+Symbolic links encountered in the tree traversal are not followed.
+.It Fl h
+Treat symbolic links like other files: modify links instead of
+following them.
+The
+.Fl h
+and
+.Fl R
+options are mutually exclusive.
+.It Fl L
+If the
+.Fl R
+option is also specified, all symbolic links are followed.
+.It Fl P
+If the
+.Fl R
+option is also specified, no symbolic links are followed.
+.It Fl R
+Recurse.
+Where
+.Ar file
+is a directory,
+change the flags of the directory and all the files and directories
+in the file hierarchy below it.
+.El
+.Pp
+Flags are a comma separated list of keywords.
+The following keywords are currently defined:
+.Bd -literal -offset indent
+arch set the archived flag (superuser only)
+nodump set the nodump flag (owner or superuser only)
+sappnd set the system append-only flag (superuser only)
+schg set the system immutable flag (superuser only)
+uappnd set the user append-only flag (owner or superuser only)
+uchg set the user immutable flag (owner or superuser only)
+.Ed
+.Pp
+The
+.Dq arch
+flag is for compatibility only,
+and currently has no effect.
+.Pp
+A file with the
+.Dq nodump
+flag set will by default only be backed up by
+.Xr dump 8
+during full backups.
+The
+.Fl h
+option of
+.Xr dump 8
+can be used to alter this.
+.Pp
+An immutable file may not be changed, moved, or deleted.
+An append-only file is immutable except that data may be appended to it.
+.Pp
+The
+superuser-settable
+.Dq sappnd
+and
+.Dq schg
+flags can be set at any time, but may only be cleared when the system is
+running at security level 0 or \-1
+(insecure or permanently insecure mode, respectively).
+For more information on setting the system security level,
+see
+.Xr securelevel 7 .
+.Pp
+Putting the letters
+.Dq no
+before a flag name causes the flag to be turned off.
+For example:
+.Pp
+.Dl nouchg the immutable bit should be cleared
+.Pp
+The
+.Fl H ,
+.Fl L ,
+and
+.Fl P
+options are ignored unless the
+.Fl R
+option is specified.
+In addition, these options override each other and the
+command's actions are determined by the last one specified.
+.Sh EXIT STATUS
+.Ex -std chflags
+.Sh SEE ALSO
+.Xr ls 1 ,
+.Xr chflags 2 ,
+.Xr stat 2 ,
+.Xr fts 3 ,
+.Xr securelevel 7 ,
+.Xr symlink 7 ,
+.Xr dump 8
+.Sh HISTORY
+The
+.Nm
+command first appeared in
+.Bx 4.4 .
diff --git a/bin/chmod/chgrp.1 b/bin/chmod/chgrp.1
new file mode 100644
index 0000000..2b0a5ec
--- /dev/null
+++ b/bin/chmod/chgrp.1
@@ -0,0 +1,140 @@
+.\" $OpenBSD: chgrp.1,v 1.17 2015/12/31 23:38:16 guenther Exp $
+.\"
+.\" Copyright (c) 1983, 1990, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the Institute of Electrical and Electronics Engineers, Inc.
+.\"
+.\" 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. 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.
+.\"
+.\" from: @(#)chgrp.1 8.3 (Berkeley) 3/31/94
+.\"
+.Dd $Mdocdate: December 31 2015 $
+.Dt CHGRP 1
+.Os
+.Sh NAME
+.Nm chgrp
+.Nd change group
+.Sh SYNOPSIS
+.Nm chgrp
+.Op Fl h
+.Oo
+.Fl R
+.Op Fl H | L | P
+.Oc
+.Ar group
+.Ar
+.Sh DESCRIPTION
+.Nm
+sets the group ID of the specified files.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl H
+If the
+.Fl R
+option is specified, symbolic links on the command line are followed.
+Symbolic links encountered in the tree traversal are not followed.
+.It Fl h
+Treat symbolic links like other files: modify links instead of
+following them.
+The
+.Fl h
+and
+.Fl R
+options are mutually exclusive.
+.It Fl L
+If the
+.Fl R
+option is specified, all symbolic links are followed.
+.It Fl P
+If the
+.Fl R
+option is specified, no symbolic links are followed.
+.It Fl R
+Recurse.
+Where
+.Ar file
+is a directory,
+change the group ID of the directory and all the files and directories
+in the file hierarchy below it.
+.El
+.Pp
+The
+.Fl H ,
+.Fl L ,
+and
+.Fl P
+options are ignored unless the
+.Fl R
+option is specified;
+if none of them are given,
+the default is to not follow symbolic links.
+In addition, these options override each other and the
+command's actions are determined by the last one specified.
+.Pp
+The
+.Ar group
+operand can be either a group name from the group database,
+or a numeric group ID.
+If a group name is also a numeric group ID, the operand is used as a
+group name.
+.Pp
+By default,
+.Nm
+clears the set-user-ID and set-group-ID bits on the file
+to prevent accidental or mischievous creation of
+set-user-ID and set-group-ID programs.
+This behaviour can be overridden by setting the
+.Xr sysctl 8
+variable
+.Va fs.posix.setuid
+to zero.
+.Pp
+The user invoking
+.Nm
+must belong to the specified group and be the owner of the file,
+or be the superuser.
+.Sh FILES
+.Bl -tag -width /etc/group -compact
+.It Pa /etc/group
+group ID file
+.El
+.Sh EXIT STATUS
+.Ex -std chgrp
+.Sh SEE ALSO
+.Xr chown 2 ,
+.Xr fts 3 ,
+.Xr group 5 ,
+.Xr passwd 5 ,
+.Xr symlink 7 ,
+.Xr chown 8
+.Sh STANDARDS
+The
+.Nm
+utility is compliant with the
+.St -p1003.1-2008
+specification.
diff --git a/bin/chmod/chmod.1 b/bin/chmod/chmod.1
new file mode 100644
index 0000000..3f979fa
--- /dev/null
+++ b/bin/chmod/chmod.1
@@ -0,0 +1,397 @@
+.\" $OpenBSD: chmod.1,v 1.41 2015/12/31 23:38:16 guenther Exp $
+.\" $NetBSD: chmod.1,v 1.8 1995/03/21 09:02:07 cgd Exp $
+.\"
+.\" Copyright (c) 1989, 1990, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the Institute of Electrical and Electronics Engineers, Inc.
+.\"
+.\" 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. 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.
+.\"
+.\" @(#)chmod.1 8.4 (Berkeley) 3/31/94
+.\"
+.Dd $Mdocdate: December 31 2015 $
+.Dt CHMOD 1
+.Os
+.Sh NAME
+.Nm chmod
+.Nd change file modes
+.Sh SYNOPSIS
+.Nm chmod
+.Op Fl h
+.Oo
+.Fl R
+.Op Fl H | L | P
+.Oc
+.Ar mode
+.Ar
+.Sh DESCRIPTION
+The
+.Nm
+utility modifies the file mode bits of the listed files
+as specified by the
+.Ar mode
+operand.
+The mode of a file dictates its permissions, among other attributes.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl H
+If the
+.Fl R
+option is also specified, symbolic links on the command line are followed.
+Symbolic links encountered in the tree traversal are not followed.
+.It Fl h
+Treat symbolic links like other files: modify links instead of
+following them.
+The
+.Fl h
+and
+.Fl R
+options are mutually exclusive.
+.It Fl L
+If the
+.Fl R
+option is also specified, all symbolic links are followed.
+.It Fl P
+If the
+.Fl R
+option is also specified, no symbolic links are followed.
+.It Fl R
+Recurse.
+Where
+.Ar file
+is a directory,
+change the mode of the directory and all the files and directories
+in the file hierarchy below it.
+.El
+.Pp
+Symbolic links have modes,
+but those modes have no effect on the kernel's access checks.
+The
+.Fl H ,
+.Fl L ,
+and
+.Fl P
+options are ignored unless the
+.Fl R
+option is specified;
+if none of them are given,
+the default is to not follow symbolic links.
+In addition, these options override each other and the
+command's actions are determined by the last one specified.
+.Pp
+Only the file's owner or the superuser is permitted to change
+the mode of a file.
+.Ss Absolute modes
+Absolute modes are specified according to the following format:
+.Bd -filled -offset indent
+.Nm chmod
+.Ar nnnn
+.Ar
+.Ed
+.Pp
+An absolute mode is an octal number (specified as
+.Ar nnnn ,
+where
+.Ar n
+is a number from 0 to 7) constructed by ORing
+any of the following values:
+.Pp
+.Bl -tag -width 6n -compact -offset indent
+.It Li 0400
+Allow read by owner.
+.It Li 0200
+Allow write by owner.
+.It Li 0100
+Allow execution (or search in directories) by owner.
+.It Li 0700
+Allow read, write, and execute/search by owner.
+.It Li 0040
+Allow read by group.
+.It Li 0020
+Allow write by group.
+.It Li 0010
+Allow execution (or search in directories) by group.
+.It Li 0070
+Allow read, write, and execute/search by group.
+.It Li 0004
+Allow read by others.
+.It Li 0002
+Allow write by others.
+.It Li 0001
+Allow execution (or search in directories) by others.
+.It Li 0007
+Allow read, write, and execute/search by others.
+.El
+.Pp
+In addition to the file permission modes, the following mode bits are
+available:
+.Pp
+.Bl -tag -width 6n -compact -offset indent
+.It Li 4000
+Set-user-ID on execution.
+.It Li 2000
+Set-group-ID on execution.
+.It Li 1000
+Enable sticky bit; see
+.Xr sticky 8
+and
+.Xr chmod 2 .
+.El
+.Pp
+The execute bit for a directory is often referred to as the
+.Dq search
+bit.
+In order to access a file, a user must have execute permission in each
+directory leading up to it in the filesystem hierarchy.
+For example, to access the file
+.Pa /bin/ls ,
+execute permission is needed on
+.Pa / ,
+.Pa /bin ,
+and, of course, the
+.Pa ls
+binary itself.
+.Ss Symbolic modes
+Symbolic modes are specified according to the following format:
+.Bd -filled -offset indent
+.Nm chmod
+.Sm off
+.Op Ar who
+.Ar op
+.Oo Ar perm Oc , Ar ...
+.Sm on
+.Ar
+.Ed
+.Pp
+The
+.Ar who
+symbols indicate whose permissions are to be changed or assigned:
+.Pp
+.Bl -tag -width 4n -compact -offset indent
+.It u
+User (owner) permissions.
+.It g
+Group permissions.
+.It o
+Others permissions.
+.It a
+All of the above.
+.El
+.Pp
+Do not confuse the
+.Sq o
+symbol with
+.Dq owner .
+It is the user bit,
+.Sq u ,
+that refers to the owner of the file.
+.Pp
+The
+.Ar op
+symbols represent the operation performed, as follows:
+.Bl -tag -width 4n -offset indent
+.It +
+If no value is supplied for
+.Ar perm ,
+the
+.Sq +
+operation has no effect.
+If no value is supplied for
+.Ar who ,
+each permission bit specified in
+.Ar perm ,
+for which the corresponding bit in the file mode creation mask
+is clear, is set.
+Otherwise, the mode bits represented by the specified
+.Ar who
+and
+.Ar perm
+values are set.
+.It \&\-
+If no value is supplied for
+.Ar perm ,
+the
+.Sq \-
+operation has no effect.
+If no value is supplied for
+.Ar who ,
+each permission bit specified in
+.Ar perm ,
+for which the corresponding bit in the file mode creation mask
+is clear, is cleared.
+Otherwise, the mode bits represented by the specified
+.Ar who
+and
+.Ar perm
+values are cleared.
+.It =
+The mode bits specified by the
+.Ar who
+value are cleared or, if no
+.Ar who
+value is specified, the user, group
+and other mode bits are cleared.
+Then, if no value is supplied for
+.Ar who ,
+each permission bit specified in
+.Ar perm ,
+for which the corresponding bit in the file mode creation mask
+is clear, is set.
+Otherwise, the mode bits represented by the specified
+.Ar who
+and
+.Ar perm
+values are set.
+.El
+.Pp
+The
+.Ar perm
+(permission symbols) represent the portions of the mode bits as follows:
+.Pp
+.Bl -tag -width Ds -compact -offset indent
+.It r
+Read bits.
+.It s
+Set-user-ID and set-group-ID on execution bits.
+.It t
+Sticky bit.
+.It w
+Write bits.
+.It x
+Execute/search bits.
+.It X
+The execute/search bits if the file is a directory or any of the
+execute/search bits are set in the original (unmodified) mode.
+Operations with the
+.Ar perm
+symbol
+.Sq X
+are only meaningful in conjunction with the
+.Ar op
+symbol
+.Sq + ,
+and are ignored in all other cases.
+.It u
+User permission bits in the mode of the original file.
+.It g
+Group permission bits in the mode of the original file.
+.It o
+Other permission bits in the mode of the original file.
+.El
+.Pp
+Each clause (given in a comma-delimited list on the command line) specifies
+one or more operations to be performed on the mode bits, and each operation is
+applied in the order specified.
+.Pp
+Operations upon the
+.Dq other
+permissions (specified by the symbol
+.Sq o
+by itself), in combination with the
+.Ar perm
+symbols
+.Sq s
+or
+.Sq t ,
+are ignored.
+.Sh EXIT STATUS
+.Ex -std chmod
+.Sh EXAMPLES
+Set file readable by anyone and writable by the owner only:
+.Pp
+.Dl $ chmod 644 file
+.Pp
+Deny write permission to group and others:
+.Pp
+.Dl $ chmod go-w file
+.Pp
+Set the read and write permissions to the usual defaults, but
+retain any execute permissions that are currently set:
+.Pp
+.Dl $ chmod =rw,+X file
+.Pp
+Make a directory or file searchable/executable by everyone if it is
+already searchable/executable by anyone:
+.Pp
+.Dl $ chmod +X file
+.Pp
+Any of these commands will make a file readable/executable by everyone and
+writable by the owner only:
+.Bd -literal -offset indent
+$ chmod 755 file
+$ chmod u=rwx,go=rx file
+$ chmod u=rwx,go=u-w file
+.Ed
+.Pp
+Clear all mode bits for group and others:
+.Pp
+.Dl $ chmod go= file
+.Pp
+Set the group bits equal to the user bits, but clear the group write bit:
+.Pp
+.Dl $ chmod g=u-w file
+.Sh SEE ALSO
+.Xr chflags 1 ,
+.Xr chgrp 1 ,
+.Xr find 1 ,
+.Xr install 1 ,
+.Xr chmod 2 ,
+.Xr stat 2 ,
+.Xr umask 2 ,
+.Xr fts 3 ,
+.Xr setmode 3 ,
+.Xr symlink 7 ,
+.Xr chown 8 ,
+.Xr sticky 8
+.Sh STANDARDS
+The
+.Nm
+utility is compliant with the
+.St -p1003.1-2008
+specification.
+.Pp
+The flags
+.Op Fl HLP
+are extensions to that specification.
+.Pp
+The
+.Sq t
+perm symbol (sticky bit) is marked by
+.St -p1003.1-2008
+as being an
+X/Open System Interfaces
+option.
+.Sh HISTORY
+A
+.Nm
+command appeared in
+.At v1 .
+.Sh BUGS
+There's no
+.Ar perm
+option for the naughty bits.
diff --git a/bin/chmod/chmod.c b/bin/chmod/chmod.c
new file mode 100644
index 0000000..d453d00
--- /dev/null
+++ b/bin/chmod/chmod.c
@@ -0,0 +1,377 @@
+/* $OpenBSD: chmod.c,v 1.39 2015/12/31 23:38:16 guenther Exp $ */
+/* $NetBSD: chmod.c,v 1.12 1995/03/21 09:02:09 cgd Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993, 1994
+ * 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. 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.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fts.h>
+#include <grp.h>
+#include <limits.h>
+#include <locale.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+int ischflags, ischown, ischgrp, ischmod;
+extern char *__progname;
+
+gid_t a_gid(const char *);
+uid_t a_uid(const char *, int);
+__dead void usage(void);
+
+int
+main(int argc, char *argv[])
+{
+ FTS *ftsp;
+ FTSENT *p;
+ void *set;
+ unsigned long val;
+ int oct;
+ mode_t omode;
+ int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval, atflags;
+ uid_t uid;
+ gid_t gid;
+ u_int32_t fclear, fset;
+ char *ep, *mode, *cp, *flags;
+
+ setlocale(LC_ALL, "");
+
+ if (strlen(__progname) > 2) {
+ ischown = __progname[2] == 'o';
+ ischgrp = __progname[2] == 'g';
+ ischmod = __progname[2] == 'm';
+#if 0
+ ischflags = __progname[2] == 'f';
+#else
+ ischflags = 0;
+#endif
+ }
+
+ uid = (uid_t)-1;
+ gid = (gid_t)-1;
+ Hflag = Lflag = Rflag = fflag = hflag = 0;
+ while ((ch = getopt(argc, argv, "HLPRXfghorstuwx")) != -1)
+ switch (ch) {
+ case 'H':
+ Hflag = 1;
+ Lflag = 0;
+ break;
+ case 'L':
+ Lflag = 1;
+ Hflag = 0;
+ break;
+ case 'P':
+ Hflag = Lflag = 0;
+ break;
+ case 'R':
+ Rflag = 1;
+ break;
+ case 'f': /* no longer documented. */
+ fflag = 1;
+ break;
+ case 'h':
+ hflag = 1;
+ break;
+ /*
+ * If this is a symbolic mode argument rather than
+ * an option, we are done with option processing.
+ */
+ case 'g': case 'o': case 'r': case 's':
+ case 't': case 'u': case 'w': case 'X': case 'x':
+ if (!ischmod)
+ usage();
+ /*
+ * If getopt() moved past the argument, back up.
+ * If the argument contains option letters before
+ * mode letters, setmode() will catch them.
+ */
+ if (optind > 1) {
+ cp = argv[optind - 1];
+ if (cp[strlen(cp) - 1] == ch)
+ --optind;
+ }
+ goto done;
+ default:
+ usage();
+ }
+done:
+ argv += optind;
+ argc -= optind;
+
+ if (argc < 2)
+ usage();
+
+ /*
+ * We alter the symlink itself if doing -h or -RP, or
+ * if doing -RH and the symlink wasn't a command line arg.
+ */
+ atflags = AT_SYMLINK_NOFOLLOW;
+
+ fts_options = FTS_PHYSICAL;
+ if (Rflag) {
+ if (hflag)
+ errx(1,
+ "the -R and -h options may not be specified together.");
+ if (Hflag)
+ fts_options |= FTS_COMFOLLOW;
+ if (Lflag) {
+ fts_options &= ~FTS_PHYSICAL;
+ fts_options |= FTS_LOGICAL;
+ atflags = 0;
+ }
+ } else if (!hflag) {
+#if !defined(__OpenBSD__)
+ fts_options = FTS_LOGICAL;
+#endif
+ atflags = 0;
+ }
+
+#if 0
+ if (ischflags) {
+ if (pledge("stdio rpath fattr", NULL) == -1)
+ err(1, "pledge");
+
+ flags = *argv;
+ if (*flags >= '0' && *flags <= '7') {
+ errno = 0;
+ val = strtoul(flags, &ep, 8);
+ if (val > UINT_MAX)
+ errno = ERANGE;
+ if (errno)
+ err(1, "invalid flags: %s", flags);
+ if (*ep)
+ errx(1, "invalid flags: %s", flags);
+ fset = val;
+ oct = 1;
+ } else {
+ if (strtofflags(&flags, &fset, &fclear))
+ errx(1, "invalid flag: %s", flags);
+ fclear = ~fclear;
+ oct = 0;
+ }
+ } else if (ischmod) {
+#else
+ if (ischmod) {
+#endif
+ mode = *argv;
+ if (*mode >= '0' && *mode <= '7') {
+ errno = 0;
+ val = strtoul(mode, &ep, 8);
+ if (val > INT_MAX)
+ errno = ERANGE;
+ if (errno)
+ err(1, "invalid file mode: %s", mode);
+ if (*ep)
+ errx(1, "invalid file mode: %s", mode);
+ omode = val;
+ oct = 1;
+ } else {
+ if ((set = setmode(mode)) == NULL)
+ errx(1, "invalid file mode: %s", mode);
+ oct = 0;
+ }
+ } else if (ischown) {
+ /* Both UID and GID are given. */
+ if ((cp = strchr(*argv, ':')) != NULL) {
+ *cp++ = '\0';
+ gid = a_gid(cp);
+ }
+#ifdef SUPPORT_DOT
+ /* UID and GID are separated by a dot and UID exists. */
+ else if ((cp = strchr(*argv, '.')) != NULL &&
+ (uid = a_uid(*argv, 1)) == (uid_t)-1) {
+ *cp++ = '\0';
+ gid = a_gid(cp);
+ }
+#endif
+ if (uid == (uid_t)-1)
+ uid = a_uid(*argv, 0);
+ } else
+ gid = a_gid(*argv);
+
+ if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL)
+ err(1, NULL);
+ for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
+ switch (p->fts_info) {
+ case FTS_D:
+ if (!Rflag)
+ fts_set(ftsp, p, FTS_SKIP);
+ if (ischmod)
+ break;
+ else
+ continue;
+ case FTS_DNR: /* Warn, chmod, continue. */
+ warnc(p->fts_errno, "%s", p->fts_path);
+ rval = 1;
+ break;
+ case FTS_DP: /* Already changed at FTS_D. */
+ if (ischmod)
+ continue;
+ else
+ break;
+ case FTS_ERR: /* Warn, continue. */
+ case FTS_NS:
+ warnc(p->fts_errno, "%s", p->fts_path);
+ rval = 1;
+ continue;
+ case FTS_SL: /* Ignore. */
+ case FTS_SLNONE:
+ /*
+ * The only symlinks that end up here are ones that
+ * don't point to anything or that loop and ones
+ * that we found doing a physical walk.
+ */
+ if (!hflag && (fts_options & FTS_LOGICAL))
+ continue;
+#if !defined(__OpenBSD__)
+ /* linux doesnt support symlink permissions */
+ if (atflags) {
+ warnx("skipping link");
+ continue;
+ }
+#endif
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * For -RH, the decision of how to handle symlinks depends
+ * on the level: follow it iff it's a command line arg.
+ */
+ if (fts_options & FTS_COMFOLLOW) {
+ atflags = p->fts_level == FTS_ROOTLEVEL ? 0 :
+ AT_SYMLINK_NOFOLLOW;
+ }
+
+ if (ischmod) {
+ if (!fchmodat(AT_FDCWD, p->fts_accpath, oct ? omode :
+ getmode(set, p->fts_statp->st_mode), atflags)
+ || fflag)
+ continue;
+ } else if (!ischflags) {
+ if (!fchownat(AT_FDCWD, p->fts_accpath, uid, gid,
+ atflags) || fflag)
+ continue;
+#if 0
+ } else {
+ if (!chflagsat(AT_FDCWD, p->fts_accpath, oct ? fset :
+ (p->fts_statp->st_flags | fset) & fclear, atflags))
+ continue;
+#endif
+ }
+
+ /* error case */
+ warn("%s", p->fts_path);
+ rval = 1;
+ }
+ if (errno)
+ err(1, "fts_read");
+ fts_close(ftsp);
+ exit(rval);
+}
+
+/*
+ * Given a UID or user name in a string, return the UID. If an empty string
+ * was given, returns -1. If silent is 0, exits on invalid user names/UIDs;
+ * otherwise, returns -1.
+ */
+uid_t
+a_uid(const char *s, int silent)
+{
+ struct passwd *pw;
+ const char *errstr;
+ uid_t uid;
+
+ if (*s == '\0') /* Argument was "[:.]gid". */
+ return ((uid_t)-1);
+
+ /* User name was given. */
+ if ((pw = getpwnam(s)) != NULL)
+ return (pw->pw_uid);
+
+ /* UID was given. */
+ uid = (uid_t)strtonum(s, 0, UID_MAX, &errstr);
+ if (errstr) {
+ if (silent)
+ return ((uid_t)-1);
+ else
+ errx(1, "user is %s: %s", errstr, s);
+ }
+
+ return (uid);
+}
+
+/*
+ * Given a GID or group name in a string, return the GID. If an empty string
+ * was given, returns -1. Exits on invalid user names/UIDs.
+ */
+gid_t
+a_gid(const char *s)
+{
+ struct group *gr;
+ const char *errstr;
+ gid_t gid;
+
+ if (*s == '\0') /* Argument was "uid[:.]". */
+ return ((gid_t)-1);
+
+ /* Group name was given. */
+ if ((gr = getgrnam(s)) != NULL)
+ return (gr->gr_gid);
+
+ /* GID was given. */
+ gid = (gid_t)strtonum(s, 0, GID_MAX, &errstr);
+ if (errstr)
+ errx(1, "group is %s: %s", errstr, s);
+
+ return (gid);
+}
+
+void
+usage(void)
+{
+ fprintf(stderr,
+ "usage: %s [-h] [-R [-H | -L | -P]] %s file ...\n",
+ __progname, ischmod ? "mode" : ischflags ? "flags" :
+ ischown ? "owner[:group]" : "group");
+ if (ischown)
+ fprintf(stderr,
+ " %s [-h] [-R [-H | -L | -P]] :group file ...\n",
+ __progname);
+ exit(1);
+}
diff --git a/bin/chmod/chown.8 b/bin/chmod/chown.8
new file mode 100644
index 0000000..f433977
--- /dev/null
+++ b/bin/chmod/chown.8
@@ -0,0 +1,172 @@
+.\" $OpenBSD: chown.8,v 1.20 2015/12/31 23:38:16 guenther Exp $
+.\"
+.\" Copyright (c) 1990, 1991, 1993, 1994
+.\" 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. 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.
+.\"
+.\" from: @(#)chown.8 8.3 (Berkeley) 3/31/94
+.\"
+.Dd $Mdocdate: December 31 2015 $
+.Dt CHOWN 8
+.Os
+.Sh NAME
+.Nm chown
+.Nd change file owner and group
+.Sh SYNOPSIS
+.Nm chown
+.Op Fl h
+.Oo
+.Fl R
+.Op Fl H | L | P
+.Oc
+.Ar owner Ns Op : Ns Ar group
+.Ar
+.Nm chown
+.Op Fl h
+.Oo
+.Fl R
+.Op Fl H | L | P
+.Oc
+.Pf : Ar group
+.Ar
+.Sh DESCRIPTION
+.Nm
+sets the user ID and/or the group ID of the specified files.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl H
+If the
+.Fl R
+option is specified, symbolic links on the command line are followed.
+Symbolic links encountered in the tree traversal are not followed.
+.It Fl h
+Treat symbolic links like other files: modify links instead of
+following them.
+The
+.Fl h
+and
+.Fl R
+options are mutually exclusive.
+.It Fl L
+If the
+.Fl R
+option is specified, all symbolic links are followed.
+.It Fl P
+If the
+.Fl R
+option is specified, no symbolic links are followed.
+.It Fl R
+Recurse.
+Where
+.Ar file
+is a directory,
+change the user ID and/or the group ID of the directory
+and all the files and directories in the file hierarchy below it.
+.El
+.Pp
+The
+.Fl H ,
+.Fl L ,
+and
+.Fl P
+options are ignored unless the
+.Fl R
+option is specified;
+if none of them are given,
+the default is to not follow symbolic links.
+In addition, these options override each other and the
+command's actions are determined by the last one specified.
+.Pp
+The
+.Ar owner
+and
+.Ar group
+operands are both optional; however, one must be specified.
+If the
+.Ar group
+operand is specified, it must be preceded by a colon
+.Pq Sq \&:
+character.
+.Pp
+The
+.Ar owner
+may be either a numeric user ID or a user name.
+If a user name is also a numeric user ID, the operand is used as a
+user name.
+The
+.Ar group
+may be either a numeric group ID or a group name.
+If a group name is also a numeric group ID, the operand is used as a
+group name.
+.Pp
+By default,
+.Nm
+clears the set-user-ID and set-group-ID bits on the file
+to prevent accidental or mischievous creation of
+set-user-ID and set-group-ID programs.
+This behaviour can be overridden by setting the
+.Xr sysctl 8
+variable
+.Va fs.posix.setuid
+to zero.
+.Pp
+Only the superuser is permitted to change the owner of a file.
+.Sh EXIT STATUS
+.Ex -std chown
+.Sh SEE ALSO
+.Xr chgrp 1 ,
+.Xr find 1 ,
+.Xr chown 2 ,
+.Xr fts 3 ,
+.Xr symlink 7
+.Sh STANDARDS
+The
+.Nm
+utility is compliant with the
+.St -p1003.1-2008
+specification.
+.Pp
+The ability to specify
+.Ar group
+without
+.Ar owner
+is an extension to that specification.
+.Pp
+Some
+.Pf non- Bx
+systems may allow the (non-privileged) owner of a file to change
+its ownership.
+.Pp
+Previous versions of the
+.Nm
+utility used the dot
+.Pq Sq \&.
+character to distinguish the group name.
+This has been changed to be a colon
+.Pq Sq \&:
+character so that user and
+group names may contain the dot character.
diff --git a/bin/cp/Makefile b/bin/cp/Makefile
new file mode 100644
index 0000000..d48e19a
--- /dev/null
+++ b/bin/cp/Makefile
@@ -0,0 +1,6 @@
+# $OpenBSD: Makefile,v 1.3 1997/09/21 11:34:47 deraadt Exp $
+
+PROG= cp
+SRCS= cp.c utils.c
+
+include bsd.prog.mk
diff --git a/bin/cp/cp.1 b/bin/cp/cp.1
new file mode 100644
index 0000000..8573d80
--- /dev/null
+++ b/bin/cp/cp.1
@@ -0,0 +1,250 @@
+.\" $OpenBSD: cp.1,v 1.37 2014/03/19 14:42:44 tedu Exp $
+.\" $NetBSD: cp.1,v 1.9 1995/07/25 19:36:45 jtc Exp $
+.\"
+.\" Copyright (c) 1989, 1990, 1993, 1994
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the Institute of Electrical and Electronics Engineers, Inc.
+.\"
+.\" 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. 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.
+.\"
+.\" @(#)cp.1 8.3 (Berkeley) 4/18/94
+.\"
+.Dd $Mdocdate: March 19 2014 $
+.Dt CP 1
+.Os
+.Sh NAME
+.Nm cp
+.Nd copy files
+.Sh SYNOPSIS
+.Nm cp
+.Op Fl fip
+.Oo
+.Fl R
+.Op Fl H | L | P
+.Oc
+.Ar source target
+.Nm cp
+.Op Fl fip
+.Oo
+.Fl R
+.Op Fl H | L | P
+.Oc
+.Ar source ... directory
+.Sh DESCRIPTION
+In the first synopsis form, the
+.Nm
+utility copies the contents of the
+.Ar source
+file to the
+.Ar target
+file.
+In the second synopsis form,
+the contents of each named
+.Ar source
+file are copied to the destination
+.Ar directory .
+The names of the files themselves are not changed.
+If
+.Nm
+detects an attempt to copy a file to itself, the copy will fail.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl f
+For each existing destination pathname, remove it and
+create a new file, without prompting for confirmation,
+regardless of its permissions.
+The
+.Fl f
+option overrides any previous
+.Fl i
+options.
+.It Fl H
+If the
+.Fl R
+option is also specified, symbolic links on the command line are followed.
+Symbolic links encountered in the tree traversal are not followed.
+.It Fl i
+Write a prompt to the standard error output before copying a file
+that would overwrite an existing file.
+If the response from the standard input begins with the character
+.Sq Li y ,
+the file copy is attempted.
+The
+.Fl i
+option overrides any previous
+.Fl f
+options.
+.It Fl L
+If the
+.Fl R
+option is also specified, all symbolic links are followed.
+.It Fl P
+If the
+.Fl R
+option is also specified, no symbolic links are followed.
+.It Fl p
+Preserve in the copy as many of the modification time, access time,
+file flags, file mode, user ID, and group ID as allowed by permissions.
+.Pp
+If the user ID and group ID cannot be preserved, no error message
+is displayed and the exit value is not altered.
+.Pp
+If the source file has its set-user-ID bit on and the user ID cannot
+be preserved, the set-user-ID bit is not preserved
+in the copy's permissions.
+If the source file has its set-group-ID bit on and the group ID cannot
+be preserved, the set-group-ID bit is not preserved
+in the copy's permissions.
+If the source file has both its set-user-ID and set-group-ID bits on,
+and either the user ID or group ID cannot be preserved, neither
+the set-user-ID nor set-group-ID bits are preserved in the copy's
+permissions.
+.It Fl R
+If
+.Ar source
+designates a directory,
+.Nm
+copies the directory and the entire subtree connected at that point.
+Created directories have the same mode as the corresponding source
+directory, unmodified by the process's umask.
+.Pp
+This option also causes symbolic links to be copied, rather than
+followed, and
+special files to be created, rather than being copied as normal files.
+However,
+.Nm
+copies hard linked files as separate files.
+To preserve hard links,
+use a utility such as
+.Xr pax 1
+or
+.Xr tar 1
+instead.
+.El
+.Pp
+For each destination file that already exists, its contents are
+overwritten if permissions allow, but its mode, user ID, and group
+ID are unchanged.
+.Pp
+In the second synopsis form,
+the destination specified by the
+.Ar directory
+operand must exist unless there is only one named
+.Ar source
+which is a directory and the
+.Fl R
+flag is specified.
+.Pp
+If the destination file does not exist, the mode of the source file is
+used as modified by the file mode creation mask
+.Pf ( Ic umask ,
+see
+.Xr csh 1 ) .
+If the source file has its set-user-ID bit on, that bit is removed
+unless both the source file and the destination file are owned by the
+same user.
+If the source file has its set-group-ID bit on, that bit is removed
+unless both the source file and the destination file are in the same
+group and the user is a member of that group.
+If both the set-user-ID and set-group-ID bits are set, all of the above
+conditions must be fulfilled or both bits are removed.
+.Pp
+Appropriate permissions are required for file creation or overwriting.
+.Pp
+When a file containing large blocks of zero-valued bytes is copied,
+.Nm
+will attempt to create a sparse file.
+.Pp
+Symbolic links are always followed unless the
+.Fl R
+flag is set, in which case symbolic links are not followed, by default.
+The
+.Fl H
+or
+.Fl L
+flags (in conjunction with the
+.Fl R
+flag) cause symbolic links to be followed as described above.
+The
+.Fl H ,
+.Fl L ,
+and
+.Fl P
+options are ignored unless the
+.Fl R
+option is specified.
+In addition, these options override each other and the
+command's actions are determined by the last one specified.
+.Sh EXIT STATUS
+.Ex -std cp
+.Sh EXAMPLES
+Make a copy of file
+.Pa foo
+named
+.Pa bar :
+.Pp
+.Dl $ cp foo bar
+.Pp
+Copy a group of files to the
+.Pa /tmp
+directory:
+.Pp
+.Dl $ cp *.txt /tmp
+.Pp
+Copy the directory
+.Pa junk
+and all of its contents (including any subdirectories) to the
+.Pa /tmp
+directory:
+.Pp
+.Dl $ cp -R junk /tmp
+.Sh SEE ALSO
+.Xr mv 1 ,
+.Xr umask 2 ,
+.Xr fts 3 ,
+.Xr symlink 7
+.Sh STANDARDS
+The
+.Nm
+utility is compliant with the
+.St -p1003.1-2008
+specification.
+.Pp
+Historic versions of the
+.Nm
+utility had a
+.Fl r
+option.
+This implementation supports that option; however, its use is strongly
+discouraged, as it does not correctly copy special files, symbolic links
+or FIFOs.
+.Sh HISTORY
+A
+.Nm
+command appeared in
+.At v1 .
diff --git a/bin/cp/cp.c b/bin/cp/cp.c
new file mode 100644
index 0000000..0d0d87a
--- /dev/null
+++ b/bin/cp/cp.c
@@ -0,0 +1,454 @@
+/* $OpenBSD: cp.c,v 1.43 2016/03/07 18:56:33 tb Exp $ */
+/* $NetBSD: cp.c,v 1.14 1995/09/07 06:14:51 jtc Exp $ */
+
+/*
+ * Copyright (c) 1988, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * David Hitz of Auspex Systems Inc.
+ *
+ * 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. 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.
+ */
+
+/*
+ * Cp copies source files to target files.
+ *
+ * The global PATH_T structure "to" always contains the path to the
+ * current target file. Since fts(3) does not change directories,
+ * this path can be either absolute or dot-relative.
+ *
+ * The basic algorithm is to initialize "to" and use fts(3) to traverse
+ * the file hierarchy rooted in the argument list. A trivial case is the
+ * case of 'cp file1 file2'. The more interesting case is the case of
+ * 'cp file1 file2 ... fileN dir' where the hierarchy is traversed and the
+ * path (relative to the root of the traversal) is appended to dir (stored
+ * in "to") to form the final target path.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+
+#include <dirent.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fts.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include "extern.h"
+
+#define fts_dne(_x) (_x->fts_pointer != NULL)
+
+PATH_T to = { to.p_path, "" };
+
+uid_t myuid;
+int Rflag, fflag, iflag, pflag, rflag;
+mode_t myumask;
+
+enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE };
+
+int copy(char *[], enum op, int);
+char *find_last_component(char *);
+
+int
+main(int argc, char *argv[])
+{
+ struct stat to_stat, tmp_stat;
+ enum op type;
+ int Hflag, Lflag, Pflag, ch, fts_options, r;
+ char *target;
+
+ (void)setlocale(LC_ALL, "");
+
+ Hflag = Lflag = Pflag = Rflag = 0;
+ while ((ch = getopt(argc, argv, "HLPRfipr")) != -1)
+ switch (ch) {
+ case 'H':
+ Hflag = 1;
+ Lflag = Pflag = 0;
+ break;
+ case 'L':
+ Lflag = 1;
+ Hflag = Pflag = 0;
+ break;
+ case 'P':
+ Pflag = 1;
+ Hflag = Lflag = 0;
+ break;
+ case 'R':
+ Rflag = 1;
+ break;
+ case 'f':
+ fflag = 1;
+ iflag = 0;
+ break;
+ case 'i':
+ iflag = 1;
+ fflag = 0;
+ break;
+ case 'p':
+ pflag = 1;
+ break;
+ case 'r':
+ rflag = 1;
+ break;
+ default:
+ usage();
+ break;
+ }
+ argc -= optind;
+ argv += optind;
+
+ /*
+ * Unfortunately, -R will use mkfifo & mknod;
+ * -p will use fchown, fchmod, lchown, fchflags..
+ */
+ if (Rflag == 0 && pflag == 0)
+ if (pledge("stdio rpath wpath cpath fattr", NULL) == -1)
+ err(1, "pledge");
+
+ if (argc < 2)
+ usage();
+
+ fts_options = FTS_NOCHDIR | FTS_PHYSICAL;
+ if (rflag) {
+ if (Rflag)
+ errx(1,
+ "the -R and -r options may not be specified together.");
+ if (Hflag || Lflag || Pflag)
+ errx(1,
+ "the -H, -L, and -P options may not be specified with the -r option.");
+ fts_options &= ~FTS_PHYSICAL;
+ fts_options |= FTS_LOGICAL;
+ }
+ if (Rflag) {
+ if (Hflag)
+ fts_options |= FTS_COMFOLLOW;
+ if (Lflag) {
+ fts_options &= ~FTS_PHYSICAL;
+ fts_options |= FTS_LOGICAL;
+ }
+ } else {
+ fts_options &= ~FTS_PHYSICAL;
+ fts_options |= FTS_LOGICAL;
+ }
+
+ myuid = getuid();
+
+ /* Copy the umask for explicit mode setting. */
+ myumask = umask(0);
+ (void)umask(myumask);
+
+ /* Save the target base in "to". */
+ target = argv[--argc];
+ if (strlcpy(to.p_path, target, sizeof to.p_path) >= sizeof(to.p_path))
+ errx(1, "%s: name too long", target);
+ to.p_end = to.p_path + strlen(to.p_path);
+ if (to.p_path == to.p_end) {
+ *to.p_end++ = '.';
+ *to.p_end = '\0';
+ }
+ to.target_end = to.p_end;
+
+ /* Set end of argument list for fts(3). */
+ argv[argc] = NULL;
+
+ /*
+ * Cp has two distinct cases:
+ *
+ * cp [-R] source target
+ * cp [-R] source1 ... sourceN directory
+ *
+ * In both cases, source can be either a file or a directory.
+ *
+ * In (1), the target becomes a copy of the source. That is, if the
+ * source is a file, the target will be a file, and likewise for
+ * directories.
+ *
+ * In (2), the real target is not directory, but "directory/source".
+ */
+ r = stat(to.p_path, &to_stat);
+ if (r == -1 && errno != ENOENT)
+ err(1, "%s", to.p_path);
+ if (r == -1 || !S_ISDIR(to_stat.st_mode)) {
+ /*
+ * Case (1). Target is not a directory.
+ */
+ if (argc > 1)
+ usage();
+ /*
+ * Need to detect the case:
+ * cp -R dir foo
+ * Where dir is a directory and foo does not exist, where
+ * we want pathname concatenations turned on but not for
+ * the initial mkdir().
+ */
+ if (r == -1) {
+ if (rflag || (Rflag && (Lflag || Hflag)))
+ stat(*argv, &tmp_stat);
+ else
+ lstat(*argv, &tmp_stat);
+
+ if (S_ISDIR(tmp_stat.st_mode) && (Rflag || rflag))
+ type = DIR_TO_DNE;
+ else
+ type = FILE_TO_FILE;
+ } else
+ type = FILE_TO_FILE;
+ } else {
+ /*
+ * Case (2). Target is a directory.
+ */
+ type = FILE_TO_DIR;
+ }
+
+ exit(copy(argv, type, fts_options));
+}
+
+char *
+find_last_component(char *path)
+{
+ char *p;
+
+ if ((p = strrchr(path, '/')) == NULL)
+ p = path;
+ else {
+ /* Special case foo/ */
+ if (!*(p+1)) {
+ while ((p >= path) && *p == '/')
+ p--;
+
+ while ((p >= path) && *p != '/')
+ p--;
+ }
+
+ p++;
+ }
+
+ return (p);
+}
+
+int
+copy(char *argv[], enum op type, int fts_options)
+{
+ struct stat to_stat;
+ FTS *ftsp;
+ FTSENT *curr;
+ int base, nlen, rval;
+ char *p, *target_mid;
+ base = 0;
+
+ if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL)
+ err(1, NULL);
+ for (rval = 0; (curr = fts_read(ftsp)) != NULL;) {
+ switch (curr->fts_info) {
+ case FTS_NS:
+ case FTS_DNR:
+ case FTS_ERR:
+ warnx("%s: %s",
+ curr->fts_path, strerror(curr->fts_errno));
+ rval = 1;
+ continue;
+ case FTS_DC:
+ warnx("%s: directory causes a cycle", curr->fts_path);
+ rval = 1;
+ continue;
+ }
+
+ /*
+ * If we are in case (2) or (3) above, we need to append the
+ * source name to the target name.
+ */
+ if (type != FILE_TO_FILE) {
+ /*
+ * Need to remember the roots of traversals to create
+ * correct pathnames. If there's a directory being
+ * copied to a non-existent directory, e.g.
+ * cp -R a/dir noexist
+ * the resulting path name should be noexist/foo, not
+ * noexist/dir/foo (where foo is a file in dir), which
+ * is the case where the target exists.
+ *
+ * Also, check for "..". This is for correct path
+ * concatenation for paths ending in "..", e.g.
+ * cp -R .. /tmp
+ * Paths ending in ".." are changed to ".". This is
+ * tricky, but seems the easiest way to fix the problem.
+ *
+ * XXX
+ * Since the first level MUST be FTS_ROOTLEVEL, base
+ * is always initialized.
+ */
+ if (curr->fts_level == FTS_ROOTLEVEL) {
+ if (type != DIR_TO_DNE) {
+ p = find_last_component(curr->fts_path);
+ base = p - curr->fts_path;
+
+ if (!strcmp(&curr->fts_path[base],
+ ".."))
+ base += 1;
+ } else
+ base = curr->fts_pathlen;
+ }
+
+ p = &curr->fts_path[base];
+ nlen = curr->fts_pathlen - base;
+ target_mid = to.target_end;
+ if (*p != '/' && target_mid[-1] != '/')
+ *target_mid++ = '/';
+ *target_mid = '\0';
+ if (target_mid - to.p_path + nlen >= PATH_MAX) {
+ warnx("%s%s: name too long (not copied)",
+ to.p_path, p);
+ rval = 1;
+ continue;
+ }
+ (void)strncat(target_mid, p, nlen);
+ to.p_end = target_mid + nlen;
+ *to.p_end = '\0';
+ }
+
+ /* Not an error but need to remember it happened */
+ if (stat(to.p_path, &to_stat) == -1) {
+ if (curr->fts_info == FTS_DP)
+ continue;
+ /*
+ * We use fts_pointer as a boolean to indicate that
+ * we created this directory ourselves. We'll use
+ * this later on via the fts_dne macro to decide
+ * whether or not to set the directory mode during
+ * the post-order pass.
+ */
+ curr->fts_pointer = (void *)1;
+ } else {
+ /*
+ * Set directory mode/user/times on the post-order
+ * pass. We can't do this earlier because the mode
+ * may not allow us write permission. Furthermore,
+ * if we set the times during the pre-order pass,
+ * they will get changed later when the directory
+ * is populated.
+ */
+ if (curr->fts_info == FTS_DP) {
+ if (!S_ISDIR(to_stat.st_mode))
+ continue;
+ /*
+ * If not -p and directory didn't exist, set
+ * it to be the same as the from directory,
+ * unmodified by the umask; arguably wrong,
+ * but it's been that way forever.
+ */
+ if (pflag && setfile(curr->fts_statp, -1))
+ rval = 1;
+ else if (fts_dne(curr))
+ (void)chmod(to.p_path,
+ curr->fts_statp->st_mode);
+ continue;
+ }
+ if (to_stat.st_dev == curr->fts_statp->st_dev &&
+ to_stat.st_ino == curr->fts_statp->st_ino) {
+ warnx("%s and %s are identical (not copied).",
+ to.p_path, curr->fts_path);
+ rval = 1;
+ if (S_ISDIR(curr->fts_statp->st_mode))
+ (void)fts_set(ftsp, curr, FTS_SKIP);
+ continue;
+ }
+ if (!S_ISDIR(curr->fts_statp->st_mode) &&
+ S_ISDIR(to_stat.st_mode)) {
+ warnx("cannot overwrite directory %s with non-directory %s",
+ to.p_path, curr->fts_path);
+ rval = 1;
+ continue;
+ }
+ }
+
+ switch (curr->fts_statp->st_mode & S_IFMT) {
+ case S_IFLNK:
+ if (copy_link(curr, !fts_dne(curr)))
+ rval = 1;
+ break;
+ case S_IFDIR:
+ if (!Rflag && !rflag) {
+ warnx("%s is a directory (not copied).",
+ curr->fts_path);
+ (void)fts_set(ftsp, curr, FTS_SKIP);
+ rval = 1;
+ break;
+ }
+ /*
+ * If the directory doesn't exist, create the new
+ * one with the from file mode plus owner RWX bits,
+ * modified by the umask. Trade-off between being
+ * able to write the directory (if from directory is
+ * 555) and not causing a permissions race. If the
+ * umask blocks owner writes, we fail..
+ */
+ if (fts_dne(curr)) {
+ if (mkdir(to.p_path,
+ curr->fts_statp->st_mode | S_IRWXU) < 0)
+ err(1, "%s", to.p_path);
+ } else if (!S_ISDIR(to_stat.st_mode))
+ errc(1, ENOTDIR, "%s", to.p_path);
+ break;
+ case S_IFBLK:
+ case S_IFCHR:
+ if (Rflag) {
+ if (copy_special(curr->fts_statp, !fts_dne(curr)))
+ rval = 1;
+ } else
+ if (copy_file(curr, fts_dne(curr)))
+ rval = 1;
+ break;
+ case S_IFIFO:
+ if (Rflag) {
+ if (copy_fifo(curr->fts_statp, !fts_dne(curr)))
+ rval = 1;
+ } else
+ if (copy_file(curr, fts_dne(curr)))
+ rval = 1;
+ break;
+ case S_IFSOCK:
+ warnc(EOPNOTSUPP, "%s", curr->fts_path);
+ break;
+ default:
+ if (copy_file(curr, fts_dne(curr)))
+ rval = 1;
+ break;
+ }
+ }
+ if (errno)
+ err(1, "fts_read");
+ (void)fts_close(ftsp);
+ return (rval);
+}
diff --git a/bin/cp/extern.h b/bin/cp/extern.h
new file mode 100644
index 0000000..42b9431
--- /dev/null
+++ b/bin/cp/extern.h
@@ -0,0 +1,54 @@
+/* $OpenBSD: extern.h,v 1.15 2015/12/26 18:11:43 guenther Exp $ */
+/* $NetBSD: extern.h,v 1.3 1995/03/21 09:02:16 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * 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. 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.
+ *
+ * @(#)extern.h 8.2 (Berkeley) 4/1/94
+ */
+
+typedef struct {
+ char *p_end; /* pointer to NULL at end of path */
+ char *target_end; /* pointer to end of target base */
+ char p_path[PATH_MAX]; /* pointer to the start of a path */
+} PATH_T;
+
+extern PATH_T to;
+extern uid_t myuid;
+extern int fflag, iflag, pflag;
+extern mode_t myumask;
+extern char *__progname;
+
+__BEGIN_DECLS
+int copy_fifo(struct stat *, int);
+int copy_file(FTSENT *, int);
+int copy_link(FTSENT *, int);
+int copy_special(struct stat *, int);
+int setfile(struct stat *, int);
+void usage(void);
+__END_DECLS
diff --git a/bin/cp/utils.c b/bin/cp/utils.c
new file mode 100644
index 0000000..e579608
--- /dev/null
+++ b/bin/cp/utils.c
@@ -0,0 +1,320 @@
+/* $OpenBSD: utils.c,v 1.39 2015/12/26 18:11:43 guenther Exp $ */
+/* $NetBSD: utils.c,v 1.6 1997/02/26 14:40:51 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * 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. 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.
+ */
+
+#include <sys/param.h> /* MAXBSIZE */
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fts.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include "extern.h"
+
+int
+copy_file(FTSENT *entp, int dne)
+{
+ static char *buf;
+ static char *zeroes;
+ struct stat to_stat, *fs;
+ int ch, checkch, from_fd, rcount, rval, to_fd, wcount;
+#ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED
+ char *p;
+#endif
+
+ if (!buf) {
+ buf = malloc(MAXBSIZE);
+ if (!buf)
+ err(1, "malloc");
+ }
+ if (!zeroes) {
+ zeroes = calloc(1, MAXBSIZE);
+ if (!zeroes)
+ err(1, "calloc");
+ }
+
+ if ((from_fd = open(entp->fts_path, O_RDONLY, 0)) == -1) {
+ warn("%s", entp->fts_path);
+ return (1);
+ }
+
+ fs = entp->fts_statp;
+
+ /*
+ * In -f (force) mode, we always unlink the destination first
+ * if it exists. Note that -i and -f are mutually exclusive.
+ */
+ if (!dne && fflag)
+ (void)unlink(to.p_path);
+
+ /*
+ * If the file exists and we're interactive, verify with the user.
+ * If the file DNE, set the mode to be the from file, minus setuid
+ * bits, modified by the umask; arguably wrong, but it makes copying
+ * executables work right and it's been that way forever. (The
+ * other choice is 666 or'ed with the execute bits on the from file
+ * modified by the umask.)
+ */
+ if (!dne && !fflag) {
+ if (iflag) {
+ (void)fprintf(stderr, "overwrite %s? ", to.p_path);
+ checkch = ch = getchar();
+ while (ch != '\n' && ch != EOF)
+ ch = getchar();
+ if (checkch != 'y' && checkch != 'Y') {
+ (void)close(from_fd);
+ return (0);
+ }
+ }
+ to_fd = open(to.p_path, O_WRONLY | O_TRUNC, 0);
+ } else
+ to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT,
+ fs->st_mode & ~(S_ISVTX | S_ISUID | S_ISGID));
+ /* XXX: PORT: wtf? S_ISTXT vs S_ISVTX */
+
+ if (to_fd == -1) {
+ warn("%s", to.p_path);
+ (void)close(from_fd);
+ return (1);
+ }
+
+ rval = 0;
+
+ /*
+ * Mmap and write if less than 8M (the limit is so we don't totally
+ * trash memory on big files. This is really a minor hack, but it
+ * wins some CPU back.
+ */
+#ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED
+ /* XXX broken for 0-size mmap */
+ if (fs->st_size <= 8 * 1048576) {
+ if ((p = mmap(NULL, (size_t)fs->st_size, PROT_READ,
+ MAP_FILE|MAP_SHARED, from_fd, (off_t)0)) == MAP_FAILED) {
+ warn("mmap: %s", entp->fts_path);
+ rval = 1;
+ } else {
+ madvise(p, fs->st_size, MADV_SEQUENTIAL);
+ if (write(to_fd, p, fs->st_size) != fs->st_size) {
+ warn("%s", to.p_path);
+ rval = 1;
+ }
+ /* Some systems don't unmap on close(2). */
+ if (munmap(p, fs->st_size) < 0) {
+ warn("%s", entp->fts_path);
+ rval = 1;
+ }
+ }
+ } else
+#endif
+ {
+ int skipholes = 0;
+ struct stat tosb;
+ if (!fstat(to_fd, &tosb) && S_ISREG(tosb.st_mode))
+ skipholes = 1;
+ while ((rcount = read(from_fd, buf, MAXBSIZE)) > 0) {
+ if (skipholes && memcmp(buf, zeroes, rcount) == 0)
+ wcount = lseek(to_fd, rcount, SEEK_CUR) == -1 ? -1 : rcount;
+ else
+ wcount = write(to_fd, buf, rcount);
+ if (rcount != wcount || wcount == -1) {
+ warn("%s", to.p_path);
+ rval = 1;
+ break;
+ }
+ }
+ if (skipholes && rcount >= 0)
+ rcount = ftruncate(to_fd, lseek(to_fd, 0, SEEK_CUR));
+ if (rcount < 0) {
+ warn("%s", entp->fts_path);
+ rval = 1;
+ }
+ }
+
+ if (rval == 1) {
+ (void)close(from_fd);
+ (void)close(to_fd);
+ return (1);
+ }
+
+ if (pflag && setfile(fs, to_fd))
+ rval = 1;
+ /*
+ * If the source was setuid or setgid, lose the bits unless the
+ * copy is owned by the same user and group.
+ */
+#define RETAINBITS \
+ (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
+ if (!pflag && dne &&
+ fs->st_mode & (S_ISUID | S_ISGID) && fs->st_uid == myuid) {
+ if (fstat(to_fd, &to_stat)) {
+ warn("%s", to.p_path);
+ rval = 1;
+ } else if (fs->st_gid == to_stat.st_gid &&
+ fchmod(to_fd, fs->st_mode & RETAINBITS & ~myumask)) {
+ warn("%s", to.p_path);
+ rval = 1;
+ }
+ }
+ (void)close(from_fd);
+ if (close(to_fd)) {
+ warn("%s", to.p_path);
+ rval = 1;
+ }
+ return (rval);
+}
+
+int
+copy_link(FTSENT *p, int exists)
+{
+ int len;
+ char name[PATH_MAX];
+
+ if ((len = readlink(p->fts_path, name, sizeof(name)-1)) == -1) {
+ warn("readlink: %s", p->fts_path);
+ return (1);
+ }
+ name[len] = '\0';
+ if (exists && unlink(to.p_path)) {
+ warn("unlink: %s", to.p_path);
+ return (1);
+ }
+ if (symlink(name, to.p_path)) {
+ warn("symlink: %s", name);
+ return (1);
+ }
+ return (pflag ? setfile(p->fts_statp, -1) : 0);
+}
+
+int
+copy_fifo(struct stat *from_stat, int exists)
+{
+ if (exists && unlink(to.p_path)) {
+ warn("unlink: %s", to.p_path);
+ return (1);
+ }
+ if (mkfifo(to.p_path, from_stat->st_mode)) {
+ warn("mkfifo: %s", to.p_path);
+ return (1);
+ }
+ return (pflag ? setfile(from_stat, -1) : 0);
+}
+
+int
+copy_special(struct stat *from_stat, int exists)
+{
+ if (exists && unlink(to.p_path)) {
+ warn("unlink: %s", to.p_path);
+ return (1);
+ }
+ if (mknod(to.p_path, from_stat->st_mode, from_stat->st_rdev)) {
+ warn("mknod: %s", to.p_path);
+ return (1);
+ }
+ return (pflag ? setfile(from_stat, -1) : 0);
+}
+
+
+int
+setfile(struct stat *fs, int fd)
+{
+ struct timespec ts[2];
+ int rval;
+
+ rval = 0;
+ fs->st_mode &= S_ISVTX | S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;
+ /* XXX: PORT: wtf? S_ISTXT vs S_ISVTX */
+
+ ts[0] = fs->st_atim;
+ ts[1] = fs->st_mtim;
+ if (fd >= 0 ? futimens(fd, ts) :
+ utimensat(AT_FDCWD, to.p_path, ts, AT_SYMLINK_NOFOLLOW)) {
+ warn("update times: %s", to.p_path);
+ rval = 1;
+ }
+ /*
+ * Changing the ownership probably won't succeed, unless we're root
+ * or POSIX_CHOWN_RESTRICTED is not set. Set uid/gid before setting
+ * the mode; current BSD behavior is to remove all setuid bits on
+ * chown. If chown fails, lose setuid/setgid bits.
+ */
+ if (fd >= 0 ? fchown(fd, fs->st_uid, fs->st_gid) :
+ lchown(to.p_path, fs->st_uid, fs->st_gid)) {
+ if (errno != EPERM) {
+ warn("chown: %s", to.p_path);
+ rval = 1;
+ }
+ fs->st_mode &= ~(S_ISVTX | S_ISUID | S_ISGID);
+ /* XXX: PORT: wtf? S_ISTXT vs S_ISVTX */
+ }
+ if (fd >= 0 ? fchmod(fd, fs->st_mode) :
+ fchmodat(AT_FDCWD, to.p_path, fs->st_mode, AT_SYMLINK_NOFOLLOW)) {
+ warn("chmod: %s", to.p_path);
+ rval = 1;
+ }
+
+#if 0
+ /*
+ * XXX
+ * NFS doesn't support chflags; ignore errors unless there's reason
+ * to believe we're losing bits. (Note, this still won't be right
+ * if the server supports flags and we were trying to *remove* flags
+ * on a file that we copied, i.e., that we didn't create.)
+ */
+ errno = 0;
+ if (fd >= 0 ? fchflags(fd, fs->st_flags) :
+ chflagsat(AT_FDCWD, to.p_path, fs->st_flags, AT_SYMLINK_NOFOLLOW))
+ if (errno != EOPNOTSUPP || fs->st_flags != 0) {
+ warn("chflags: %s", to.p_path);
+ rval = 1;
+ }
+#endif
+ return (rval);
+}
+
+
+void
+usage(void)
+{
+ (void)fprintf(stderr,
+ "usage: %s [-fip] [-R [-H | -L | -P]] source target\n", __progname);
+ (void)fprintf(stderr,
+ " %s [-fip] [-R [-H | -L | -P]] source ... directory\n",
+ __progname);
+ exit(1);
+}
diff --git a/bin/date/Makefile b/bin/date/Makefile
new file mode 100644
index 0000000..6edb89a
--- /dev/null
+++ b/bin/date/Makefile
@@ -0,0 +1,8 @@
+# $OpenBSD: Makefile,v 1.4 2011/07/07 21:00:59 deraadt Exp $
+
+PROG= date
+SRCS= date.c
+DPADD+= ${LIBUTIL}
+LDADD+= -lutil
+
+include bsd.prog.mk
diff --git a/bin/date/date.1 b/bin/date/date.1
new file mode 100644
index 0000000..a24aed2
--- /dev/null
+++ b/bin/date/date.1
@@ -0,0 +1,248 @@
+.\" $OpenBSD: date.1,v 1.66 2015/09/25 16:02:54 schwarze Exp $
+.\" $NetBSD: date.1,v 1.12 1996/03/12 04:32:37 phil Exp $
+.\"
+.\" Copyright (c) 1980, 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the Institute of Electrical and Electronics Engineers, Inc.
+.\"
+.\" 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. 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.
+.\"
+.\" @(#)date.1 8.3 (Berkeley) 4/28/95
+.\"
+.Dd $Mdocdate: September 25 2015 $
+.Dt DATE 1
+.Os
+.Sh NAME
+.Nm date
+.Nd display or set date and time
+.Sh SYNOPSIS
+.Nm date
+.Op Fl aju
+.Op Fl d Ar dst
+.Op Fl r Ar seconds
+.Op Fl t Ar minutes_west
+.Op Fl z Ar output_zone
+.Op Cm + Ns Ar format
+.Sm off
+.Oo Oo Oo Oo Oo Oo
+.Ar cc Oc
+.Ar yy Oc
+.Ar mm Oc
+.Ar dd Oc
+.Ar HH Oc
+.Ar MM
+.Op . Ar SS
+.Oc
+.Sm on
+.Sh DESCRIPTION
+When invoked without arguments, the
+.Nm
+utility displays the current date and time.
+Otherwise, depending on the options specified,
+.Nm
+will set the date and time or print it in a user-defined way.
+.Pp
+Changing the system date has some risks, as described in
+.Xr settimeofday 2 .
+Only the superuser may change the date.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl a
+Use the
+.Xr adjtime 2
+call to gradually skew the local time to the
+remote time rather than just hopping.
+.It Fl d Ar dst
+Set the system's value for Daylight Saving Time.
+If
+.Ar dst
+is non-zero, future calls
+to
+.Xr gettimeofday 2
+will return a non-zero value for
+.Fa tz_dsttime .
+.It Fl j
+Parse the provided date and time and display the result without changing
+the clock.
+.It Fl r Ar seconds
+Print out (in specified format) the date and time represented by
+.Ar seconds
+from the Epoch.
+.It Fl t Ar minutes_west
+Set the system's value for minutes west of GMT.
+.Ar minutes_west
+specifies the number of minutes returned in
+.Fa tz_minuteswest
+by future calls to
+.Xr gettimeofday 2 .
+.It Fl u
+Display or set the date in UTC (Coordinated Universal) time.
+.It Fl z Ar output_zone
+Just before printing the time, change to the specified timezone;
+see the description of
+.Ev TZ
+below.
+This can be used with
+.Fl j
+to easily convert time specifications from one zone to another.
+.El
+.Pp
+An operand with a leading plus sign
+.Pq Sq +
+signals a user-defined format
+string which specifies the format in which to display the date and time.
+The format string may contain any of the conversion specifications described
+in the
+.Xr strftime 3
+manual page, as well as any arbitrary text.
+A newline
+.Pq Ql \en
+character is always output after the characters specified by
+the format string.
+The format string for the default display is:
+.Bd -literal -offset indent
+%a %b %e %H:%M:%S %Z %Y
+.Ed
+.Pp
+If an operand does not have a leading plus sign, it is interpreted as
+a value for setting the system's notion of the current date and time.
+The canonical representation for setting the date and time is:
+.Pp
+.Bl -tag -width Ds -compact -offset indent
+.It Ar ccyy
+Year.
+If yy is specified, but cc is not,
+a value for yy between 69 and 99 results in a cc value of 19.
+Otherwise, a cc value of 20 is used.
+.It Ar mm
+Month:
+a number from 1 to 12.
+.It Ar dd
+Day:
+a number from 1 to 31.
+.It Ar HH
+Hour:
+a number from 0 to 23.
+.It Ar MM
+Minute:
+a number from 0 to 59.
+.It Ar SS
+Second:
+a number from 0 to 60
+(permitting a leap second),
+preceded by a period.
+.El
+.Pp
+Everything but the minute is optional.
+.Pp
+Time changes for Daylight Saving Time, standard time, leap seconds,
+and leap years are handled automatically.
+.Sh ENVIRONMENT
+.Bl -tag -width Ds
+.It Ev TZ
+The time zone to use when parsing or displaying dates.
+See
+.Xr environ 7
+for more information.
+If this variable is not set, the time zone is determined based on
+.Pa /etc/localtime ,
+which the administrator adjusts using
+the
+.Fl l
+option of
+.Xr zic 8 .
+.El
+.Sh FILES
+.Bl -tag -width /var/log/messages -compact
+.It Pa /var/log/wtmp
+record of date resets and time changes
+.It Pa /var/log/messages
+record of the user setting the time
+.El
+.Sh EXIT STATUS
+.Ex -std
+.Sh EXAMPLES
+Display the date using the specified format string:
+.Bd -literal -offset indent
+$ date "+DATE: %Y-%m-%d%nTIME: %H:%M:%S"
+DATE: 1987-11-21
+TIME: 13:36:16
+.Ed
+.Pp
+Set the date to
+June 13, 1985, 4:27 PM:
+.Pp
+.Dl # date 198506131627
+.Pp
+Set the time to
+2:32 PM,
+without modifying the date:
+.Pp
+.Dl # date 1432
+.Sh SEE ALSO
+.Xr adjtime 2 ,
+.Xr gettimeofday 2 ,
+.Xr strftime 3 ,
+.Xr utmp 5 ,
+.Xr ntpd 8 ,
+.Xr rdate 8
+.Sh STANDARDS
+The
+.Nm
+utility is compliant with the
+.St -p1003.1-2008
+specification.
+.Pp
+The flags
+.Op Fl adjrtz ,
+as well as the conversion specifiers
+.Ql \&%F ,
+.Ql \&%G ,
+.Ql \&%g ,
+.Ql \&%k ,
+.Ql \&%l ,
+.Ql \&%R ,
+.Ql \&%s ,
+.Ql \&%v ,
+and
+.Ql \&%+ ,
+are extensions to that specification.
+.Pp
+This implementation requires the traditional
+.Bx
+date format,
+[[[[[cc]yy]mm]dd]HH]MM[.SS],
+which differs from the
+X/Open System Interfaces option of the
+.St -p1003.1-2008
+specification.
+.Sh HISTORY
+A
+.Nm
+command appeared in
+.At v1 .
diff --git a/bin/date/date.c b/bin/date/date.c
new file mode 100644
index 0000000..0dd9739
--- /dev/null
+++ b/bin/date/date.c
@@ -0,0 +1,277 @@
+/* $OpenBSD: date.c,v 1.49 2015/10/09 01:37:06 deraadt Exp $ */
+/* $NetBSD: date.c,v 1.11 1995/09/07 06:21:05 jtc Exp $ */
+
+/*
+ * Copyright (c) 1985, 1987, 1988, 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. 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.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <syslog.h>
+#include <time.h>
+#include <unistd.h>
+
+extern char *__progname;
+
+time_t tval;
+int jflag;
+int slidetime;
+
+static void setthetime(char *);
+static void badformat(void);
+static void usage(void);
+
+int
+main(int argc, char *argv[])
+{
+ struct timezone tz;
+ const char *errstr;
+ struct tm *tp;
+ int ch, rflag;
+ char *format, buf[1024], *outzone = NULL;
+
+ setlocale(LC_ALL, "");
+
+ tz.tz_dsttime = tz.tz_minuteswest = 0;
+ rflag = 0;
+ while ((ch = getopt(argc, argv, "ad:jr:ut:z:")) != -1)
+ switch(ch) {
+ case 'd': /* daylight saving time */
+ tz.tz_dsttime = atoi(optarg) ? 1 : 0;
+ break;
+ case 'a':
+ slidetime = 1;
+ break;
+ case 'j': /* don't set */
+ jflag = 1;
+ break;
+ case 'r': /* user specified seconds */
+ rflag = 1;
+ tval = atoll(optarg);
+ break;
+ case 'u': /* do everything in UTC */
+ if (setenv("TZ", "UTC", 1) == -1)
+ err(1, "cannot unsetenv TZ");
+ break;
+ case 't': /* minutes west of GMT */
+ tz.tz_minuteswest = strtonum(optarg, 0, 24*60-1, &errstr);
+ if (errstr)
+ errx(1, "-t %s: %s", optarg, errstr);
+ break;
+ case 'z':
+ outzone = optarg;
+ break;
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ /*
+ * If -d or -t, set the timezone or daylight saving time; this
+ * doesn't belong here, the kernel should not know about either.
+ */
+ if ((tz.tz_minuteswest || tz.tz_dsttime) &&
+ settimeofday(NULL, &tz))
+ err(1, "settimeofday");
+
+ if (!rflag && time(&tval) == -1)
+ err(1, "time");
+
+ format = "%a %b %e %H:%M:%S %Z %Y";
+
+ /* allow the operands in any order */
+ if (*argv && **argv == '+') {
+ format = *argv + 1;
+ argv++;
+ argc--;
+ }
+
+ if (*argv) {
+ setthetime(*argv);
+ argv++;
+ argc--;
+ }
+
+ if (pledge("stdio rpath wpath", NULL) == -1)
+ err(1, "pledge");
+
+ if (*argv && **argv == '+') {
+ format = *argv + 1;
+ argc--;
+ }
+
+ if (argc > 0)
+ errx(1, "too many arguments");
+
+ if (outzone)
+ setenv("TZ", outzone, 1);
+
+ tp = localtime(&tval);
+ if (tp == NULL)
+ errx(1, "conversion error");
+ (void)strftime(buf, sizeof(buf), format, tp);
+ (void)printf("%s\n", buf);
+ exit(0);
+}
+
+#define ATOI2(ar) ((ar) += 2, ((ar)[-2] - '0') * 10 + ((ar)[-1] - '0'))
+void
+setthetime(char *p)
+{
+ struct tm *lt;
+ struct timeval tv;
+ char *dot, *t;
+ int yearset = 0;
+
+ for (t = p, dot = NULL; *t; ++t) {
+ if (isdigit((unsigned char)*t))
+ continue;
+ if (*t == '.' && dot == NULL) {
+ dot = t;
+ continue;
+ }
+ badformat();
+ }
+
+ lt = localtime(&tval);
+
+ lt->tm_isdst = -1; /* correct for DST */
+
+ if (dot != NULL) { /* .SS */
+ *dot++ = '\0';
+ if (strlen(dot) != 2)
+ badformat();
+ lt->tm_sec = ATOI2(dot);
+ if (lt->tm_sec > 61)
+ badformat();
+ } else
+ lt->tm_sec = 0;
+
+ switch (strlen(p)) {
+ case 12: /* cc */
+ lt->tm_year = (ATOI2(p) * 100) - 1900;
+ yearset = 1;
+ /* FALLTHROUGH */
+ case 10: /* yy */
+ if (!yearset) {
+ /* mask out current year, leaving only century */
+ lt->tm_year = ((lt->tm_year / 100) * 100);
+ }
+ lt->tm_year += ATOI2(p);
+ /* FALLTHROUGH */
+ case 8: /* mm */
+ lt->tm_mon = ATOI2(p);
+ if ((lt->tm_mon > 12) || !lt->tm_mon)
+ badformat();
+ --lt->tm_mon; /* time struct is 0 - 11 */
+ /* FALLTHROUGH */
+ case 6: /* dd */
+ lt->tm_mday = ATOI2(p);
+ if ((lt->tm_mday > 31) || !lt->tm_mday)
+ badformat();
+ /* FALLTHROUGH */
+ case 4: /* HH */
+ lt->tm_hour = ATOI2(p);
+ if (lt->tm_hour > 23)
+ badformat();
+ /* FALLTHROUGH */
+ case 2: /* MM */
+ lt->tm_min = ATOI2(p);
+ if (lt->tm_min > 59)
+ badformat();
+ break;
+ default:
+ badformat();
+ }
+
+ /* convert broken-down time to UTC clock time */
+ if ((tval = mktime(lt)) < 0)
+ errx(1, "specified date is outside allowed range");
+
+ if (jflag)
+ return;
+
+ /* set the time */
+ if (slidetime) {
+ struct timeval tv_current;
+
+ if (gettimeofday(&tv_current, NULL) == -1)
+ err(1, "Could not get local time of day");
+
+ tv.tv_sec = tval - tv_current.tv_sec;
+ tv.tv_usec = 0;
+ if (adjtime(&tv, NULL) == -1)
+ errx(1, "adjtime");
+ } else {
+#if 0
+#ifndef SMALL
+ logwtmp("|", "date", "");
+#endif
+#endif
+ tv.tv_sec = tval;
+ tv.tv_usec = 0;
+ if (settimeofday(&tv, NULL))
+ err(1, "settimeofday");
+#if 0
+#ifndef SMALL
+ logwtmp("{", "date", "");
+#endif
+#endif
+ }
+
+ if ((p = getlogin()) == NULL)
+ p = "???";
+ syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p);
+}
+
+static void
+badformat(void)
+{
+ warnx("illegal time format");
+ usage();
+}
+
+static void
+usage(void)
+{
+ (void)fprintf(stderr,
+ "usage: %s [-aju] [-d dst] [-r seconds] [-t minutes_west] [-z output_zone]\n",
+ __progname);
+ (void)fprintf(stderr,
+ "%-*s[+format] [[[[[[cc]yy]mm]dd]HH]MM[.SS]]\n", (int)strlen(__progname) + 8, "");
+ exit(1);
+}
diff --git a/bin/dd/Makefile b/bin/dd/Makefile
new file mode 100644
index 0000000..641bdc9
--- /dev/null
+++ b/bin/dd/Makefile
@@ -0,0 +1,6 @@
+# $OpenBSD: Makefile,v 1.5 1998/05/29 04:34:20 rahnds Exp $
+
+PROG= dd
+SRCS= args.c conv.c conv_tab.c dd.c misc.c position.c
+
+include bsd.prog.mk
diff --git a/bin/dd/args.c b/bin/dd/args.c
new file mode 100644
index 0000000..15c5ab4
--- /dev/null
+++ b/bin/dd/args.c
@@ -0,0 +1,470 @@
+/* $OpenBSD: args.c,v 1.26 2014/09/14 22:44:47 schwarze Exp $ */
+/* $NetBSD: args.c,v 1.7 1996/03/01 01:18:58 jtc Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego and Lance
+ * Visser of Convex Computer Corporation.
+ *
+ * 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. 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.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <err.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "dd.h"
+#include "extern.h"
+
+static int c_arg(const void *, const void *);
+static void f_bs(char *);
+static void f_cbs(char *);
+static void f_conv(char *);
+static void f_count(char *);
+static void f_files(char *);
+static void f_ibs(char *);
+static void f_if(char *);
+static void f_obs(char *);
+static void f_of(char *);
+static void f_seek(char *);
+static void f_skip(char *);
+static void f_status(char *);
+static size_t get_bsz(char *);
+static off_t get_off(char *);
+
+static const struct arg {
+ const char *name;
+ void (*f)(char *);
+ u_int set, noset;
+} args[] = {
+ { "bs", f_bs, C_BS, C_BS|C_IBS|C_OBS|C_OSYNC },
+ { "cbs", f_cbs, C_CBS, C_CBS },
+ { "conv", f_conv, 0, 0 },
+ { "count", f_count, C_COUNT, C_COUNT },
+ { "files", f_files, C_FILES, C_FILES },
+ { "ibs", f_ibs, C_IBS, C_BS|C_IBS },
+ { "if", f_if, C_IF, C_IF },
+ { "obs", f_obs, C_OBS, C_BS|C_OBS },
+ { "of", f_of, C_OF, C_OF },
+ { "seek", f_seek, C_SEEK, C_SEEK },
+ { "skip", f_skip, C_SKIP, C_SKIP },
+ { "status", f_status, C_STATUS,C_STATUS },
+};
+
+static char *oper;
+
+/*
+ * args -- parse JCL syntax of dd.
+ */
+void
+jcl(char **argv)
+{
+ struct arg *ap, tmp;
+ char *arg;
+
+ in.dbsz = out.dbsz = 512;
+
+ while ((oper = *++argv) != NULL) {
+ if ((oper = strdup(oper)) == NULL)
+ errx(1, "out of memory");
+ if ((arg = strchr(oper, '=')) == NULL)
+ errx(1, "unknown operand %s", oper);
+ *arg++ = '\0';
+ if (!*arg)
+ errx(1, "no value specified for %s", oper);
+ tmp.name = oper;
+ if (!(ap = (struct arg *)bsearch(&tmp, args,
+ sizeof(args)/sizeof(struct arg), sizeof(struct arg),
+ c_arg)))
+ errx(1, "unknown operand %s", tmp.name);
+ if (ddflags & ap->noset)
+ errx(1, "%s: illegal argument combination or already set",
+ tmp.name);
+ ddflags |= ap->set;
+ ap->f(arg);
+ }
+
+ /* Final sanity checks. */
+
+ if (ddflags & C_BS) {
+ /*
+ * Bs is turned off by any conversion -- we assume the user
+ * just wanted to set both the input and output block sizes
+ * and didn't want the bs semantics, so we don't warn.
+ */
+ if (ddflags & (C_BLOCK|C_LCASE|C_SWAB|C_UCASE|C_UNBLOCK))
+ ddflags &= ~C_BS;
+
+ /* Bs supersedes ibs and obs. */
+ if (ddflags & C_BS && ddflags & (C_IBS|C_OBS))
+ warnx("bs supersedes ibs and obs");
+ }
+
+ /*
+ * Ascii/ebcdic and cbs implies block/unblock.
+ * Block/unblock requires cbs and vice-versa.
+ */
+ if (ddflags & (C_BLOCK|C_UNBLOCK)) {
+ if (!(ddflags & C_CBS))
+ errx(1, "record operations require cbs");
+ if (cbsz == 0)
+ errx(1, "cbs cannot be zero");
+ cfunc = ddflags & C_BLOCK ? block : unblock;
+ } else if (ddflags & C_CBS) {
+ if (ddflags & (C_ASCII|C_EBCDIC)) {
+ if (ddflags & C_ASCII) {
+ ddflags |= C_UNBLOCK;
+ cfunc = unblock;
+ } else {
+ ddflags |= C_BLOCK;
+ cfunc = block;
+ }
+ } else
+ errx(1, "cbs meaningless if not doing record operations");
+ if (cbsz == 0)
+ errx(1, "cbs cannot be zero");
+ } else
+ cfunc = def;
+
+ if (in.dbsz == 0 || out.dbsz == 0)
+ errx(1, "buffer sizes cannot be zero");
+
+ /*
+ * Read and write take size_t's as arguments. Lseek, however,
+ * takes an off_t (quad).
+ */
+ if (cbsz > SSIZE_MAX || in.dbsz > SSIZE_MAX || out.dbsz > SSIZE_MAX)
+ errx(1, "buffer sizes cannot be greater than %zd",
+ (ssize_t)SSIZE_MAX);
+ if (in.offset > LLONG_MAX / in.dbsz || out.offset > LLONG_MAX / out.dbsz)
+ errx(1, "seek offsets cannot be larger than %qd", LLONG_MAX);
+}
+
+static int
+c_arg(const void *a, const void *b)
+{
+
+ return (strcmp(((struct arg *)a)->name, ((struct arg *)b)->name));
+}
+
+static void
+f_bs(char *arg)
+{
+
+ in.dbsz = out.dbsz = get_bsz(arg);
+}
+
+static void
+f_cbs(char *arg)
+{
+
+ cbsz = get_bsz(arg);
+}
+
+static void
+f_count(char *arg)
+{
+
+ if ((cpy_cnt = get_bsz(arg)) == 0)
+ cpy_cnt = (size_t)-1;
+}
+
+static void
+f_files(char *arg)
+{
+
+ files_cnt = get_bsz(arg);
+}
+
+static void
+f_ibs(char *arg)
+{
+
+ if (!(ddflags & C_BS))
+ in.dbsz = get_bsz(arg);
+}
+
+static void
+f_if(char *arg)
+{
+
+ in.name = arg;
+}
+
+static void
+f_obs(char *arg)
+{
+
+ if (!(ddflags & C_BS))
+ out.dbsz = get_bsz(arg);
+}
+
+static void
+f_of(char *arg)
+{
+
+ out.name = arg;
+}
+
+static void
+f_seek(char *arg)
+{
+
+ out.offset = get_off(arg);
+}
+
+static void
+f_skip(char *arg)
+{
+
+ in.offset = get_off(arg);
+}
+
+static void
+f_status(char *arg)
+{
+
+ if (strcmp(arg, "none") == 0)
+ ddflags |= C_NOINFO;
+ else if (strcmp(arg, "noxfer") == 0)
+ ddflags |= C_NOXFER;
+ else
+ errx(1, "unknown status %s", arg);
+}
+
+
+static const struct conv {
+ const char *name;
+ u_int set, noset;
+ const u_char *ctab;
+} clist[] = {
+#ifndef NO_CONV
+ { "ascii", C_ASCII, C_EBCDIC, e2a_POSIX },
+ { "block", C_BLOCK, C_UNBLOCK, NULL },
+ { "ebcdic", C_EBCDIC, C_ASCII, a2e_POSIX },
+ { "ibm", C_EBCDIC, C_ASCII, a2ibm_POSIX },
+ { "lcase", C_LCASE, C_UCASE, NULL },
+ { "osync", C_OSYNC, C_BS, NULL },
+ { "swab", C_SWAB, 0, NULL },
+ { "sync", C_SYNC, 0, NULL },
+ { "ucase", C_UCASE, C_LCASE, NULL },
+ { "unblock", C_UNBLOCK, C_BLOCK, NULL },
+#endif
+ { "noerror", C_NOERROR, 0, NULL },
+ { "notrunc", C_NOTRUNC, 0, NULL },
+ { NULL, 0, 0, NULL }
+};
+
+static void
+f_conv(char *arg)
+{
+ const struct conv *cp;
+ const char *name;
+
+ while (arg != NULL) {
+ name = strsep(&arg, ",");
+ for (cp = &clist[0]; cp->name; cp++)
+ if (strcmp(name, cp->name) == 0)
+ break;
+ if (!cp->name)
+ errx(1, "unknown conversion %s", name);
+ if (ddflags & cp->noset)
+ errx(1, "%s: illegal conversion combination", name);
+ ddflags |= cp->set;
+ if (cp->ctab)
+ ctab = cp->ctab;
+ }
+}
+
+/*
+ * Convert an expression of the following forms to a size_t
+ * 1) A positive decimal number, optionally followed by
+ * b - multiply by 512.
+ * k, m or g - multiply by 1024 each.
+ * w - multiply by sizeof int
+ * 2) Two or more of the above, separated by x
+ * (or * for backwards compatibility), specifying
+ * the product of the indicated values.
+ */
+static size_t
+get_bsz(char *val)
+{
+ size_t num, t;
+ char *expr;
+
+ if (strchr(val, '-'))
+ errx(1, "%s: illegal numeric value", oper);
+
+ errno = 0;
+ num = strtoul(val, &expr, 0);
+ if (num == ULONG_MAX && errno == ERANGE) /* Overflow. */
+ err(1, "%s", oper);
+ if (expr == val) /* No digits. */
+ errx(1, "%s: illegal numeric value", oper);
+
+ switch(*expr) {
+ case 'b':
+ t = num;
+ num *= 512;
+ if (t > num)
+ goto erange;
+ ++expr;
+ break;
+ case 'g':
+ case 'G':
+ t = num;
+ num *= 1024;
+ if (t > num)
+ goto erange;
+ /* fallthrough */
+ case 'm':
+ case 'M':
+ t = num;
+ num *= 1024;
+ if (t > num)
+ goto erange;
+ /* fallthrough */
+ case 'k':
+ case 'K':
+ t = num;
+ num *= 1024;
+ if (t > num)
+ goto erange;
+ ++expr;
+ break;
+ case 'w':
+ t = num;
+ num *= sizeof(int);
+ if (t > num)
+ goto erange;
+ ++expr;
+ break;
+ }
+
+ switch(*expr) {
+ case '\0':
+ break;
+ case '*': /* Backward compatible. */
+ case 'x':
+ t = num;
+ num *= get_bsz(expr + 1);
+ if (t > num)
+ goto erange;
+ break;
+ default:
+ errx(1, "%s: illegal numeric value", oper);
+ }
+ return (num);
+erange:
+ errc(1, ERANGE, "%s", oper);
+}
+
+/*
+ * Convert an expression of the following forms to an off_t
+ * 1) A positive decimal number, optionally followed by
+ * b - multiply by 512.
+ * k, m or g - multiply by 1024 each.
+ * w - multiply by sizeof int
+ * 2) Two or more of the above, separated by x
+ * (or * for backwards compatibility), specifying
+ * the product of the indicated values.
+ */
+static off_t
+get_off(char *val)
+{
+ off_t num, t;
+ char *expr;
+
+ num = strtoq(val, &expr, 0);
+ if (num == LLONG_MAX) /* Overflow. */
+ err(1, "%s", oper);
+ if (expr == val) /* No digits. */
+ errx(1, "%s: illegal numeric value", oper);
+
+ switch(*expr) {
+ case 'b':
+ t = num;
+ num *= 512;
+ if (t > num)
+ goto erange;
+ ++expr;
+ break;
+ case 'g':
+ case 'G':
+ t = num;
+ num *= 1024;
+ if (t > num)
+ goto erange;
+ /* fallthrough */
+ case 'm':
+ case 'M':
+ t = num;
+ num *= 1024;
+ if (t > num)
+ goto erange;
+ /* fallthrough */
+ case 'k':
+ case 'K':
+ t = num;
+ num *= 1024;
+ if (t > num)
+ goto erange;
+ ++expr;
+ break;
+ case 'w':
+ t = num;
+ num *= sizeof(int);
+ if (t > num)
+ goto erange;
+ ++expr;
+ break;
+ }
+
+ switch(*expr) {
+ case '\0':
+ break;
+ case '*': /* Backward compatible. */
+ case 'x':
+ t = num;
+ num *= get_off(expr + 1);
+ if (t > num)
+ goto erange;
+ break;
+ default:
+ errx(1, "%s: illegal numeric value", oper);
+ }
+ return (num);
+erange:
+ errc(1, ERANGE, "%s", oper);
+}
diff --git a/bin/dd/conv.c b/bin/dd/conv.c
new file mode 100644
index 0000000..16aa5f1
--- /dev/null
+++ b/bin/dd/conv.c
@@ -0,0 +1,274 @@
+/* $OpenBSD: conv.c,v 1.12 2015/01/16 06:39:31 deraadt Exp $ */
+/* $NetBSD: conv.c,v 1.6 1996/02/20 19:29:02 jtc Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego and Lance
+ * Visser of Convex Computer Corporation.
+ *
+ * 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. 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.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <err.h>
+#include <string.h>
+
+#include "dd.h"
+#include "extern.h"
+
+#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
+
+/*
+ * def --
+ * Copy input to output. Input is buffered until reaches obs, and then
+ * output until less than obs remains. Only a single buffer is used.
+ * Worst case buffer calculation is (ibs + obs - 1).
+ */
+void
+def(void)
+{
+ size_t cnt;
+ u_char *inp;
+ const u_char *t;
+
+ if ((t = ctab) != NULL)
+ for (inp = in.dbp - (cnt = in.dbrcnt); cnt--; ++inp)
+ *inp = t[*inp];
+
+ /* Make the output buffer look right. */
+ out.dbp = in.dbp;
+ out.dbcnt = in.dbcnt;
+
+ if (in.dbcnt >= out.dbsz) {
+ /* If the output buffer is full, write it. */
+ dd_out(0);
+
+ /*
+ * Ddout copies the leftover output to the beginning of
+ * the buffer and resets the output buffer. Reset the
+ * input buffer to match it.
+ */
+ in.dbp = out.dbp;
+ in.dbcnt = out.dbcnt;
+ }
+}
+
+void
+def_close(void)
+{
+ /* Just update the count, everything is already in the buffer. */
+ if (in.dbcnt)
+ out.dbcnt = in.dbcnt;
+}
+
+#ifdef NO_CONV
+/* Build a smaller version (i.e. for a miniroot) */
+/* These can not be called, but just in case... */
+static char no_block[] = "unblock and -DNO_CONV?";
+void block() { errx(1, "%s", no_block + 2); }
+void block_close() { errx(1, "%s", no_block + 2); }
+void unblock() { errx(1, "%s", no_block); }
+void unblock_close() { errx(1, "%s", no_block); }
+#else /* NO_CONV */
+
+/*
+ * Copy variable length newline terminated records with a max size cbsz
+ * bytes to output. Records less than cbs are padded with spaces.
+ *
+ * max in buffer: MAX(ibs, cbsz)
+ * max out buffer: obs + cbsz
+ */
+void
+block(void)
+{
+ static int intrunc;
+ int ch = -1;
+ size_t cnt, maxlen;
+ u_char *inp, *outp;
+ const u_char *t;
+
+ /*
+ * Record truncation can cross block boundaries. If currently in a
+ * truncation state, keep tossing characters until reach a newline.
+ * Start at the beginning of the buffer, as the input buffer is always
+ * left empty.
+ */
+ if (intrunc) {
+ for (inp = in.db, cnt = in.dbrcnt;
+ cnt && *inp++ != '\n'; --cnt);
+ if (!cnt) {
+ in.dbcnt = 0;
+ in.dbp = in.db;
+ return;
+ }
+ intrunc = 0;
+ /* Adjust the input buffer numbers. */
+ in.dbcnt = cnt - 1;
+ in.dbp = inp + cnt - 1;
+ }
+
+ /*
+ * Copy records (max cbsz size chunks) into the output buffer. The
+ * translation is done as we copy into the output buffer.
+ */
+ for (inp = in.dbp - in.dbcnt, outp = out.dbp; in.dbcnt;) {
+ maxlen = MINIMUM(cbsz, in.dbcnt);
+ if ((t = ctab) != NULL)
+ for (cnt = 0;
+ cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)
+ *outp++ = t[ch];
+ else
+ for (cnt = 0;
+ cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)
+ *outp++ = ch;
+ /*
+ * Check for short record without a newline. Reassemble the
+ * input block.
+ */
+ if (ch != '\n' && in.dbcnt < cbsz) {
+ (void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
+ break;
+ }
+
+ /* Adjust the input buffer numbers. */
+ in.dbcnt -= cnt;
+ if (ch == '\n')
+ --in.dbcnt;
+
+ /* Pad short records with spaces. */
+ if (cnt < cbsz)
+ (void)memset(outp, ctab ? ctab[' '] : ' ', cbsz - cnt);
+ else {
+ /*
+ * If the next character wouldn't have ended the
+ * block, it's a truncation.
+ */
+ if (!in.dbcnt || *inp != '\n')
+ ++st.trunc;
+
+ /* Toss characters to a newline. */
+ for (; in.dbcnt && *inp++ != '\n'; --in.dbcnt);
+ if (!in.dbcnt)
+ intrunc = 1;
+ else
+ --in.dbcnt;
+ }
+
+ /* Adjust output buffer numbers. */
+ out.dbp += cbsz;
+ if ((out.dbcnt += cbsz) >= out.dbsz)
+ dd_out(0);
+ outp = out.dbp;
+ }
+ in.dbp = in.db + in.dbcnt;
+}
+
+void
+block_close(void)
+{
+ /*
+ * Copy any remaining data into the output buffer and pad to a record.
+ * Don't worry about truncation or translation, the input buffer is
+ * always empty when truncating, and no characters have been added for
+ * translation. The bottom line is that anything left in the input
+ * buffer is a truncated record. Anything left in the output buffer
+ * just wasn't big enough.
+ */
+ if (in.dbcnt) {
+ ++st.trunc;
+ (void)memmove(out.dbp, in.dbp - in.dbcnt, in.dbcnt);
+ (void)memset(out.dbp + in.dbcnt,
+ ctab ? ctab[' '] : ' ', cbsz - in.dbcnt);
+ out.dbcnt += cbsz;
+ }
+}
+
+/*
+ * Convert fixed length (cbsz) records to variable length. Deletes any
+ * trailing blanks and appends a newline.
+ *
+ * max in buffer: MAX(ibs, cbsz) + cbsz
+ * max out buffer: obs + cbsz
+ */
+void
+unblock(void)
+{
+ size_t cnt;
+ u_char *inp;
+ const u_char *t;
+
+ /* Translation and case conversion. */
+ if ((t = ctab) != NULL)
+ for (cnt = in.dbrcnt, inp = in.dbp - 1; cnt--; inp--)
+ *inp = t[*inp];
+ /*
+ * Copy records (max cbsz size chunks) into the output buffer. The
+ * translation has to already be done or we might not recognize the
+ * spaces.
+ */
+ for (inp = in.db; in.dbcnt >= cbsz; inp += cbsz, in.dbcnt -= cbsz) {
+ for (t = inp + cbsz - 1; t >= inp && *t == ' '; --t);
+ if (t >= inp) {
+ cnt = t - inp + 1;
+ (void)memmove(out.dbp, inp, cnt);
+ out.dbp += cnt;
+ out.dbcnt += cnt;
+ }
+ ++out.dbcnt;
+ *out.dbp++ = '\n';
+ if (out.dbcnt >= out.dbsz)
+ dd_out(0);
+ }
+ if (in.dbcnt)
+ (void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
+ in.dbp = in.db + in.dbcnt;
+}
+
+void
+unblock_close(void)
+{
+ size_t cnt;
+ u_char *t;
+
+ if (in.dbcnt) {
+ warnx("%s: short input record", in.name);
+ for (t = in.db + in.dbcnt - 1; t >= in.db && *t == ' '; --t);
+ if (t >= in.db) {
+ cnt = t - in.db + 1;
+ (void)memmove(out.dbp, in.db, cnt);
+ out.dbp += cnt;
+ out.dbcnt += cnt;
+ }
+ ++out.dbcnt;
+ *out.dbp++ = '\n';
+ }
+}
+
+#endif /* NO_CONV */
diff --git a/bin/dd/conv_tab.c b/bin/dd/conv_tab.c
new file mode 100644
index 0000000..2a2da63
--- /dev/null
+++ b/bin/dd/conv_tab.c
@@ -0,0 +1,166 @@
+/* $OpenBSD: conv_tab.c,v 1.6 2014/03/27 15:32:13 tedu Exp $ */
+/* $NetBSD: conv_tab.c,v 1.7 1996/02/20 19:29:03 jtc Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego and Lance
+ * Visser of Convex Computer Corporation.
+ *
+ * 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. 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.
+ */
+
+#include <sys/types.h>
+
+/*
+ * There are currently three tables:
+ *
+ * ebcdic -> ascii POSIX/S5 conv=ascii
+ * ascii -> ebcdic POSIX/S5 conv=ebcdic
+ * ascii -> ibm ebcdic POSIX/S5 conv=ibm
+ *
+ * Other tables are built from these if multiple conversions are being
+ * done.
+ *
+ * Tables used for conversions to/from IBM and EBCDIC to support an extension
+ * to POSIX P1003.2/D11. The tables referencing POSIX contain data extracted
+ * from tables 4-3 and 4-4 in P1003.2/Draft 11.
+ *
+ * More information can be obtained in "Correspondences of 8-Bit and Hollerith
+ * Codes for Computer Environments-A USASI Tutorial", Communications of the
+ * ACM, Volume 11, Number 11, November 1968, pp. 783-789.
+ */
+
+u_char casetab[256];
+
+/* EBCDIC to ASCII -- POSIX and System V compatible. */
+const u_char e2a_POSIX[] = {
+ 0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177, /* 0000 */
+ 0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017, /* 0010 */
+ 0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207, /* 0020 */
+ 0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037, /* 0030 */
+ 0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033, /* 0040 */
+ 0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007, /* 0050 */
+ 0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004, /* 0060 */
+ 0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032, /* 0070 */
+ 0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246, /* 0100 */
+ 0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174, /* 0110 */
+ 0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257, /* 0120 */
+ 0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176, /* 0130 */
+ 0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267, /* 0140 */
+ 0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077, /* 0150 */
+ 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301, /* 0160 */
+ 0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042, /* 0170 */
+ 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147, /* 0200 */
+ 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311, /* 0210 */
+ 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160, /* 0220 */
+ 0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320, /* 0230 */
+ 0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170, /* 0240 */
+ 0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327, /* 0250 */
+ 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337, /* 0260 */
+ 0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347, /* 0270 */
+ 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107, /* 0300 */
+ 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355, /* 0310 */
+ 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120, /* 0320 */
+ 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363, /* 0330 */
+ 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130, /* 0340 */
+ 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371, /* 0350 */
+ 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067, /* 0360 */
+ 0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377, /* 0370 */
+};
+
+/* ASCII to EBCDIC -- POSIX and System V compatible. */
+const u_char a2e_POSIX[] = {
+ 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057, /* 0000 */
+ 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017, /* 0010 */
+ 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046, /* 0020 */
+ 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037, /* 0030 */
+ 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175, /* 0040 */
+ 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141, /* 0050 */
+ 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, /* 0060 */
+ 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157, /* 0070 */
+ 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307, /* 0100 */
+ 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326, /* 0110 */
+ 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346, /* 0120 */
+ 0347, 0350, 0351, 0255, 0340, 0275, 0232, 0155, /* 0130 */
+ 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207, /* 0140 */
+ 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226, /* 0150 */
+ 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246, /* 0160 */
+ 0247, 0250, 0251, 0300, 0117, 0320, 0137, 0007, /* 0170 */
+ 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027, /* 0200 */
+ 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033, /* 0210 */
+ 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010, /* 0220 */
+ 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341, /* 0230 */
+ 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110, /* 0240 */
+ 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127, /* 0250 */
+ 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147, /* 0260 */
+ 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165, /* 0270 */
+ 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215, /* 0300 */
+ 0216, 0217, 0220, 0152, 0233, 0234, 0235, 0236, /* 0310 */
+ 0237, 0240, 0252, 0253, 0254, 0112, 0256, 0257, /* 0320 */
+ 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, /* 0330 */
+ 0270, 0271, 0272, 0273, 0274, 0241, 0276, 0277, /* 0340 */
+ 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333, /* 0350 */
+ 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355, /* 0360 */
+ 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377, /* 0370 */
+};
+
+/* ASCII to IBM EBCDIC -- POSIX and System V compatible. */
+const u_char a2ibm_POSIX[] = {
+ 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057, /* 0000 */
+ 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017, /* 0010 */
+ 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046, /* 0020 */
+ 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037, /* 0030 */
+ 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175, /* 0040 */
+ 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141, /* 0050 */
+ 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367, /* 0060 */
+ 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157, /* 0070 */
+ 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307, /* 0100 */
+ 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326, /* 0110 */
+ 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346, /* 0120 */
+ 0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155, /* 0130 */
+ 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207, /* 0140 */
+ 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226, /* 0150 */
+ 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246, /* 0160 */
+ 0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007, /* 0170 */
+ 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027, /* 0200 */
+ 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033, /* 0210 */
+ 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010, /* 0220 */
+ 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341, /* 0230 */
+ 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110, /* 0240 */
+ 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127, /* 0250 */
+ 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147, /* 0260 */
+ 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165, /* 0270 */
+ 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215, /* 0300 */
+ 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236, /* 0310 */
+ 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257, /* 0320 */
+ 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267, /* 0330 */
+ 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277, /* 0340 */
+ 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333, /* 0350 */
+ 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355, /* 0360 */
+ 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377, /* 0370 */
+};
diff --git a/bin/dd/dd.1 b/bin/dd/dd.1
new file mode 100644
index 0000000..5d3fffd
--- /dev/null
+++ b/bin/dd/dd.1
@@ -0,0 +1,380 @@
+.\" $OpenBSD: dd.1,v 1.32 2015/01/15 19:06:31 schwarze Exp $
+.\" $NetBSD: dd.1,v 1.5 1995/03/21 09:04:04 cgd Exp $
+.\"
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Keith Muller of the University of California, San Diego.
+.\"
+.\" 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. 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.
+.\"
+.\" @(#)dd.1 8.2 (Berkeley) 1/13/94
+.\"
+.Dd $Mdocdate: January 15 2015 $
+.Dt DD 1
+.Os
+.Sh NAME
+.Nm dd
+.Nd convert and copy a file
+.Sh SYNOPSIS
+.Nm dd
+.Op Ar operand ...
+.Sh DESCRIPTION
+The
+.Nm
+utility copies the standard input to the standard output, applying any
+specified conversions.
+Input data is read and written in 512-byte blocks.
+If input reads are short, input from multiple reads are aggregated
+to form the output block.
+When finished,
+.Nm
+displays the number of complete and partial input and output blocks
+and truncated input records to the standard error output.
+.Pp
+The following operands are available:
+.Bl -tag -width of=file
+.It Cm if= Ns Ar file
+Read input from
+.Ar file
+instead of the standard input.
+.It Cm of= Ns Ar file
+Write output to
+.Ar file
+instead of the standard output.
+Any regular output file is truncated unless the
+.Cm notrunc
+conversion value is specified.
+If an initial portion of the output file is skipped (see the
+.Cm seek
+operand),
+the output file is truncated at that point.
+.It Cm ibs= Ns Ar n
+Set the input block size to
+.Ar n
+bytes instead of the default 512.
+.It Cm obs= Ns Ar n
+Set the output block size to
+.Ar n
+bytes instead of the default 512.
+.It Cm bs= Ns Ar n
+Set both the input and output block size to
+.Ar n
+bytes, superseding the
+.Cm ibs
+and
+.Cm obs
+operands.
+If no conversion values other than
+.Cm noerror ,
+.Cm notrunc ,
+or
+.Cm sync
+are specified, then each input block is copied to the output as a
+single block without any aggregation of short blocks.
+.It Cm cbs= Ns Ar n
+Set the conversion record size to
+.Ar n
+bytes.
+The conversion record size is required by the record oriented conversion
+values.
+.It Cm count= Ns Ar n
+Copy only
+.Ar n
+input blocks.
+.It Cm files= Ns Ar n
+Copy
+.Ar n
+input files before terminating.
+This operand is only applicable when the input device is a tape.
+.It Cm seek= Ns Ar n
+Seek
+.Ar n
+blocks from the beginning of the output before copying.
+On non-tape devices, an
+.Xr lseek 2
+operation is used.
+Otherwise, existing blocks are read and the data discarded.
+If the user does not have read permission for the tape, it is positioned
+using the tape
+.Xr ioctl 2
+function calls.
+If the seek operation is past the end of file, space from the current
+end of file to the specified offset is filled with blocks of NUL bytes.
+.It Cm skip= Ns Ar n
+Skip
+.Ar n
+blocks from the beginning of the input before copying.
+On input which supports seeks, an
+.Xr lseek 2
+operation is used.
+Otherwise, input data is read and discarded.
+For pipes, the correct number of bytes is read.
+For all other devices, the correct number of blocks is read without
+distinguishing between a partial or complete block being read.
+.It Xo
+.Sm off
+.Cm status= Ar value
+.Sm on
+.Xc
+Where
+.Ar value
+is one of the symbols from the following list.
+.Bl -tag -width unblock
+.It Cm noxfer
+Do not print the transfer statistics as the last line of status output.
+.It Cm none
+Do not print the status output.
+Error messages are shown; informational messages are not.
+.El
+.It Xo
+.Sm off
+.Cm conv= Ar value Oo ,
+.Sm on
+.Ar value ... Oc
+.Xc
+Where
+.Ar value
+is one of the symbols from the following list.
+.Bl -tag -width unblock
+.It Cm ascii
+The same as the
+.Cm unblock
+value except that characters are translated from EBCDIC to ASCII
+before the records are converted.
+(These values imply
+.Cm unblock
+if the operand
+.Cm cbs
+is also specified.)
+.It Cm block
+Treats the input as a sequence of newline or end-of-file terminated variable
+length records independent of input and output block boundaries.
+Any trailing newline character is discarded.
+Each input record is converted to a fixed length output record where the
+length is specified by the
+.Cm cbs
+operand.
+Input records shorter than the conversion record size are padded with spaces.
+Input records longer than the conversion record size are truncated.
+The number of truncated input records, if any, is reported to the standard
+error output at the completion of the copy.
+.It Cm ebcdic , ibm
+The same as the
+.Cm block
+value except that characters are translated from ASCII to EBCDIC
+after the records are converted.
+(These values imply
+.Cm block
+if the operand
+.Cm cbs
+is also specified.)
+There are two conversion maps for EBCDIC.
+The value
+.Cm ebcdic
+specifies the recommended one which is compatible with
+.At V .
+The value
+.Cm ibm
+is a slightly different mapping, which is compatible with the
+.At V
+.Cm ibm
+value.
+.It Cm lcase
+Transform uppercase characters into lowercase characters.
+.It Cm noerror
+Do not stop processing on an input error.
+When an input error occurs, a diagnostic message followed by the current
+input and output block counts will be written to the standard error output
+in the same format as the standard completion message.
+If the
+.Cm sync
+conversion is also specified, any missing input data will be replaced
+with NUL bytes (or with spaces if a block oriented conversion value was
+specified) and processed as a normal input buffer.
+If the
+.Cm sync
+conversion is not specified, the input block is omitted from the output.
+On input files which are not tapes or pipes, the file offset
+will be positioned past the block in which the error occurred using
+.Xr lseek 2 .
+.It Cm notrunc
+Do not truncate the output file.
+This will preserve any blocks in the output file not explicitly written
+by
+.Nm dd .
+The
+.Cm notrunc
+value is not supported for tapes.
+.It Cm osync
+Pad the final output block to the full output block size.
+If the input file is not a multiple of the output block size
+after conversion, this conversion forces the final output block
+to be the same size as preceding blocks for use on devices that require
+regularly sized blocks to be written.
+This option is incompatible with use of the
+.Cm bs= Ns Ar n
+block size specification.
+.It Cm swab
+Swap every pair of input bytes.
+If an input buffer has an odd number of bytes, the last byte will be
+ignored during swapping.
+.It Cm sync
+Pad every input block to the input buffer size.
+Spaces are used for pad bytes if a block oriented conversion value is
+specified, otherwise NUL bytes are used.
+.It Cm ucase
+Transform lowercase characters into uppercase characters.
+.It Cm unblock
+Treats the input as a sequence of fixed length records independent of input
+and output block boundaries.
+The length of the input records is specified by the
+.Cm cbs
+operand.
+Any trailing space characters are discarded and a newline character is
+appended.
+.El
+.El
+.Pp
+Where sizes are specified, a decimal number of bytes is expected.
+If the number ends with a
+.Sq b ,
+.Sq k
+or
+.Sq K ,
+.Sq m
+or
+.Sq M ,
+.Sq g
+or
+.Sq G ,
+or
+.Sq w ,
+the number is multiplied by 512, 1024 (1K), 1048576 (1M), 1073741824 (1G),
+or the number of bytes in an integer, respectively.
+Two or more numbers may be separated by an
+.Sq x
+to indicate a product.
+.Pp
+When finished,
+.Nm
+displays the number of complete and partial input and output blocks,
+truncated input records, and odd-length byte-swapping blocks to the
+standard error output.
+A partial input block is one where less than the input block size
+was read.
+A partial output block is one where less than the output block size
+was written.
+Partial output blocks to tape devices are considered fatal errors.
+Otherwise, the rest of the block will be written.
+Partial output blocks to character devices will produce a warning message.
+A truncated input block is one where a variable length record oriented
+conversion value was specified and the input line was too long to
+fit in the conversion record or was not newline terminated.
+.Pp
+Normally, data resulting from input or conversion or both are aggregated
+into output blocks of the specified size.
+After the end of input is reached, any remaining output is written as
+a block.
+This means that the final output block may be shorter than the output
+block size.
+.Pp
+If
+.Nm
+receives a
+.Dv SIGINFO
+(see the
+.Dq status
+argument for
+.Xr stty 1 )
+signal, the current input and output block counts will
+be written to the standard error output
+in the same format as the standard completion message.
+If
+.Nm
+receives a
+.Dv SIGINT
+signal, the current input and output block counts will
+be written to the standard error output
+in the same format as the standard completion message and
+.Nm
+will exit.
+.Sh EXIT STATUS
+.Ex -std dd
+.Sh EXAMPLES
+Write an
+.Ox
+floppy image to a floppy disk:
+.Pp
+.Dl # dd if=floppy34.fs of=/dev/rfd0c bs=32k
+.Pp
+Create an ISO-9660 image of a CD-ROM:
+.Pp
+.Dl # dd if=/dev/rcd0c of=disk.iso bs=32k
+.Sh SEE ALSO
+.Xr cp 1 ,
+.Xr mt 1 ,
+.Xr tr 1
+.Sh STANDARDS
+The
+.Nm
+utility is compliant with the
+.St -p1003.1-2008
+specification.
+.Pp
+The conversions
+.Cm ascii ,
+.Cm ebcdic ,
+and
+.Cm ibm
+are marked by
+.St -p1003.1-2008
+as being an
+X/Open System Interfaces option.
+.Pp
+The
+.Cm files
+and
+.Cm status
+operands,
+the
+.Cm osync
+conversion,
+the
+.Sq K ,
+.Sq m ,
+.Sq M ,
+.Sq g ,
+.Sq G ,
+and
+.Sq w
+size multipliers
+and
+.Dv SIGINFO
+handling
+are all extensions to the
+.St -p1003.1-2008
+specification.
diff --git a/bin/dd/dd.c b/bin/dd/dd.c
new file mode 100644
index 0000000..73df6dd
--- /dev/null
+++ b/bin/dd/dd.c
@@ -0,0 +1,412 @@
+/* $OpenBSD: dd.c,v 1.23 2015/10/09 01:37:06 deraadt Exp $ */
+/* $NetBSD: dd.c,v 1.6 1996/02/20 19:29:06 jtc Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego and Lance
+ * Visser of Convex Computer Corporation.
+ *
+ * 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. 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.
+ */
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mtio.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "dd.h"
+#include "extern.h"
+
+static void dd_close(void);
+static void dd_in(void);
+static void getfdtype(IO *);
+static void setup(void);
+
+#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b))
+
+IO in, out; /* input/output state */
+STAT st; /* statistics */
+void (*cfunc)(void); /* conversion function */
+size_t cpy_cnt; /* # of blocks to copy */
+u_int ddflags; /* conversion options */
+size_t cbsz; /* conversion block size */
+size_t files_cnt = 1; /* # of files to copy */
+const u_char *ctab; /* conversion table */
+
+int
+main(int argc, char *argv[])
+{
+ jcl(argv);
+ setup();
+
+ (void)signal(SIGPWR, summaryx);
+ (void)signal(SIGINT, terminate);
+
+ atexit(summary);
+
+ if (cpy_cnt != (size_t)-1) {
+ while (files_cnt--)
+ dd_in();
+ }
+
+ dd_close();
+ exit(0);
+}
+
+static void
+setup(void)
+{
+ if (in.name == NULL) {
+ in.name = "stdin";
+ in.fd = STDIN_FILENO;
+ } else {
+ in.fd = open(in.name, O_RDONLY, 0);
+ if (in.fd < 0)
+ err(1, "%s", in.name);
+ }
+
+ getfdtype(&in);
+
+ if (files_cnt > 1 && !(in.flags & ISTAPE))
+ errx(1, "files is not supported for non-tape devices");
+
+ if (out.name == NULL) {
+ /* No way to check for read access here. */
+ out.fd = STDOUT_FILENO;
+ out.name = "stdout";
+ } else {
+#define OFLAGS \
+ (O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC))
+ out.fd = open(out.name, O_RDWR | OFLAGS, DEFFILEMODE);
+ /*
+ * May not have read access, so try again with write only.
+ * Without read we may have a problem if output also does
+ * not support seeks.
+ */
+ if (out.fd < 0) {
+ out.fd = open(out.name, O_WRONLY | OFLAGS, DEFFILEMODE);
+ out.flags |= NOREAD;
+ }
+ if (out.fd < 0)
+ err(1, "%s", out.name);
+ }
+
+ getfdtype(&out);
+
+ /*
+ * Allocate space for the input and output buffers. If not doing
+ * record oriented I/O, only need a single buffer.
+ */
+ if (!(ddflags & (C_BLOCK|C_UNBLOCK))) {
+ if ((in.db = malloc(out.dbsz + in.dbsz - 1)) == NULL)
+ err(1, "input buffer");
+ out.db = in.db;
+ } else if ((in.db =
+ malloc((u_int)(MAXIMUM(in.dbsz, cbsz) + cbsz))) == NULL ||
+ (out.db = malloc((u_int)(out.dbsz + cbsz))) == NULL)
+ err(1, "output buffer");
+ in.dbp = in.db;
+ out.dbp = out.db;
+
+ /* Position the input/output streams. */
+ if (in.offset)
+ pos_in();
+ if (out.offset)
+ pos_out();
+
+ if (pledge("stdio", NULL) == -1)
+ err(1, "pledge");
+
+ /*
+ * Truncate the output file; ignore errors because it fails on some
+ * kinds of output files, tapes, for example.
+ */
+ if ((ddflags & (C_OF | C_SEEK | C_NOTRUNC)) == (C_OF | C_SEEK))
+ (void)ftruncate(out.fd, out.offset * out.dbsz);
+
+ /*
+ * If converting case at the same time as another conversion, build a
+ * table that does both at once. If just converting case, use the
+ * built-in tables.
+ */
+ if (ddflags & (C_LCASE|C_UCASE)) {
+#ifdef NO_CONV
+ /* Should not get here, but just in case... */
+ errx(1, "case conv and -DNO_CONV");
+#else /* NO_CONV */
+ u_int cnt;
+ if (ddflags & C_ASCII || ddflags & C_EBCDIC) {
+ if (ddflags & C_LCASE) {
+ for (cnt = 0; cnt < 0377; ++cnt)
+ casetab[cnt] = tolower(ctab[cnt]);
+ } else {
+ for (cnt = 0; cnt < 0377; ++cnt)
+ casetab[cnt] = toupper(ctab[cnt]);
+ }
+ } else {
+ if (ddflags & C_LCASE) {
+ for (cnt = 0; cnt < 0377; ++cnt)
+ casetab[cnt] = tolower(cnt);
+ } else {
+ for (cnt = 0; cnt < 0377; ++cnt)
+ casetab[cnt] = toupper(cnt);
+ }
+ }
+
+ ctab = casetab;
+#endif /* NO_CONV */
+ }
+
+ /* Statistics timestamp. */
+ (void)gettimeofday(&st.startv, (struct timezone *)NULL);
+}
+
+static void
+getfdtype(IO *io)
+{
+ struct mtget mt;
+ struct stat sb;
+
+ if (fstat(io->fd, &sb))
+ err(1, "%s", io->name);
+ if (S_ISCHR(sb.st_mode))
+ io->flags |= ioctl(io->fd, MTIOCGET, &mt) ? ISCHR : ISTAPE;
+ if (S_ISFIFO(sb.st_mode) || S_ISSOCK(sb.st_mode))
+ io->flags |= ISPIPE;
+}
+
+static void
+swapbytes(void *v, size_t len)
+{
+ unsigned char *p = v;
+ unsigned char t;
+
+ while (len > 1) {
+ t = p[0];
+ p[0] = p[1];
+ p[1] = t;
+ p += 2;
+ len -= 2;
+ }
+}
+
+
+static void
+dd_in(void)
+{
+ ssize_t n;
+
+ for (;;) {
+ if (cpy_cnt && (st.in_full + st.in_part) >= cpy_cnt)
+ return;
+
+ /*
+ * Zero the buffer first if sync; if doing block operations
+ * use spaces.
+ */
+ if (ddflags & C_SYNC) {
+ if (ddflags & (C_BLOCK|C_UNBLOCK))
+ (void)memset(in.dbp, ' ', in.dbsz);
+ else
+ (void)memset(in.dbp, 0, in.dbsz);
+ }
+
+ n = read(in.fd, in.dbp, in.dbsz);
+ if (n == 0) {
+ in.dbrcnt = 0;
+ return;
+ }
+
+ /* Read error. */
+ if (n < 0) {
+ /*
+ * If noerror not specified, die. POSIX requires that
+ * the warning message be followed by an I/O display.
+ */
+ if (!(ddflags & C_NOERROR))
+ err(1, "%s", in.name);
+ warn("%s", in.name);
+ summary();
+
+ /*
+ * If it's not a tape drive or a pipe, seek past the
+ * error. If your OS doesn't do the right thing for
+ * raw disks this section should be modified to re-read
+ * in sector size chunks.
+ */
+ if (!(in.flags & (ISPIPE|ISTAPE)) &&
+ lseek(in.fd, (off_t)in.dbsz, SEEK_CUR))
+ warn("%s", in.name);
+
+ /* If sync not specified, omit block and continue. */
+ if (!(ddflags & C_SYNC))
+ continue;
+
+ /* Read errors count as full blocks. */
+ in.dbcnt += in.dbrcnt = in.dbsz;
+ ++st.in_full;
+
+ /* Handle full input blocks. */
+ } else if (n == in.dbsz) {
+ in.dbcnt += in.dbrcnt = n;
+ ++st.in_full;
+
+ /* Handle partial input blocks. */
+ } else {
+ /* If sync, use the entire block. */
+ if (ddflags & C_SYNC)
+ in.dbcnt += in.dbrcnt = in.dbsz;
+ else
+ in.dbcnt += in.dbrcnt = n;
+ ++st.in_part;
+ }
+
+ /*
+ * POSIX states that if bs is set and no other conversions
+ * than noerror, notrunc or sync are specified, the block
+ * is output without buffering as it is read.
+ */
+ if (ddflags & C_BS) {
+ out.dbcnt = in.dbcnt;
+ dd_out(1);
+ in.dbcnt = 0;
+ continue;
+ }
+
+ if (ddflags & C_SWAB) {
+ if ((n = in.dbrcnt) & 1) {
+ ++st.swab;
+ --n;
+ }
+ swapbytes(in.dbp, n);
+ }
+
+ in.dbp += in.dbrcnt;
+ (*cfunc)();
+ }
+}
+
+/*
+ * Cleanup any remaining I/O and flush output. If necessary, output file
+ * is truncated.
+ */
+static void
+dd_close(void)
+{
+ if (cfunc == def)
+ def_close();
+ else if (cfunc == block)
+ block_close();
+ else if (cfunc == unblock)
+ unblock_close();
+ if (ddflags & C_OSYNC && out.dbcnt && out.dbcnt < out.dbsz) {
+ if (ddflags & (C_BLOCK|C_UNBLOCK))
+ memset(out.dbp, ' ', out.dbsz - out.dbcnt);
+ else
+ memset(out.dbp, 0, out.dbsz - out.dbcnt);
+ out.dbcnt = out.dbsz;
+ }
+ if (out.dbcnt)
+ dd_out(1);
+}
+
+void
+dd_out(int force)
+{
+ static int warned;
+ size_t cnt, n;
+ ssize_t nw;
+ u_char *outp;
+
+ /*
+ * Write one or more blocks out. The common case is writing a full
+ * output block in a single write; increment the full block stats.
+ * Otherwise, we're into partial block writes. If a partial write,
+ * and it's a character device, just warn. If a tape device, quit.
+ *
+ * The partial writes represent two cases. 1: Where the input block
+ * was less than expected so the output block was less than expected.
+ * 2: Where the input block was the right size but we were forced to
+ * write the block in multiple chunks. The original versions of dd(1)
+ * never wrote a block in more than a single write, so the latter case
+ * never happened.
+ *
+ * One special case is if we're forced to do the write -- in that case
+ * we play games with the buffer size, and it's usually a partial write.
+ */
+ outp = out.db;
+ for (n = force ? out.dbcnt : out.dbsz;; n = out.dbsz) {
+ for (cnt = n;; cnt -= nw) {
+ nw = write(out.fd, outp, cnt);
+ if (nw <= 0) {
+ if (nw == 0)
+ errx(1, "%s: end of device", out.name);
+ if (errno != EINTR)
+ err(1, "%s", out.name);
+ nw = 0;
+ }
+ outp += nw;
+ st.bytes += nw;
+ if (nw == n) {
+ if (n != out.dbsz)
+ ++st.out_part;
+ else
+ ++st.out_full;
+ break;
+ }
+ ++st.out_part;
+ if (nw == cnt)
+ break;
+ if (out.flags & ISCHR && !warned) {
+ warned = 1;
+ warnx("%s: short write on character device",
+ out.name);
+ }
+ if (out.flags & ISTAPE)
+ errx(1, "%s: short write on tape device", out.name);
+ }
+ if ((out.dbcnt -= n) < out.dbsz)
+ break;
+ }
+
+ /* Reassemble the output block. */
+ if (out.dbcnt)
+ (void)memmove(out.db, out.dbp - out.dbcnt, out.dbcnt);
+ out.dbp = out.db + out.dbcnt;
+}
diff --git a/bin/dd/dd.h b/bin/dd/dd.h
new file mode 100644
index 0000000..b9f5788
--- /dev/null
+++ b/bin/dd/dd.h
@@ -0,0 +1,98 @@
+/* $OpenBSD: dd.h,v 1.6 2014/02/12 01:18:36 bluhm Exp $ */
+/* $NetBSD: dd.h,v 1.4 1995/03/21 09:04:08 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego and Lance
+ * Visser of Convex Computer Corporation.
+ *
+ * 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. 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.
+ *
+ * @(#)dd.h 8.3 (Berkeley) 4/2/94
+ */
+
+/* Input/output stream state. */
+typedef struct {
+ u_char *db; /* buffer address */
+ u_char *dbp; /* current buffer I/O address */
+ size_t dbcnt; /* current buffer byte count */
+ size_t dbrcnt; /* last read byte count */
+ size_t dbsz; /* buffer size */
+
+#define ISCHR 0x01 /* character device (warn on short) */
+#define ISPIPE 0x02 /* pipe (not truncatable) */
+#define ISTAPE 0x04 /* tape (not seekable) */
+#define NOREAD 0x08 /* not readable */
+ u_int flags;
+
+ char *name; /* name */
+ int fd; /* file descriptor */
+ off_t offset; /* # of blocks to skip */
+
+ size_t f_stats; /* # of full blocks processed */
+ size_t p_stats; /* # of partial blocks processed */
+ size_t s_stats; /* # of odd swab blocks */
+ size_t t_stats; /* # of truncations */
+} IO;
+
+typedef struct {
+ size_t in_full; /* # of full input blocks */
+ size_t in_part; /* # of partial input blocks */
+ size_t out_full; /* # of full output blocks */
+ size_t out_part; /* # of partial output blocks */
+ size_t trunc; /* # of truncated records */
+ size_t swab; /* # of odd-length swab blocks */
+ off_t bytes; /* # of bytes written */
+ struct timeval startv; /* start time of dd */
+} STAT;
+
+/* Flags (in ddflags). */
+#define C_ASCII 0x00001
+#define C_BLOCK 0x00002
+#define C_BS 0x00004
+#define C_CBS 0x00008
+#define C_COUNT 0x00010
+#define C_EBCDIC 0x00020
+#define C_FILES 0x00040
+#define C_IBS 0x00080
+#define C_IF 0x00100
+#define C_LCASE 0x00200
+#define C_NOERROR 0x00400
+#define C_NOTRUNC 0x00800
+#define C_OBS 0x01000
+#define C_OF 0x02000
+#define C_SEEK 0x04000
+#define C_SKIP 0x08000
+#define C_SWAB 0x10000
+#define C_SYNC 0x20000
+#define C_UCASE 0x40000
+#define C_UNBLOCK 0x80000
+#define C_OSYNC 0x100000
+#define C_STATUS 0x200000
+#define C_NOXFER 0x400000
+#define C_NOINFO 0x800000
diff --git a/bin/dd/extern.h b/bin/dd/extern.h
new file mode 100644
index 0000000..4b933ce
--- /dev/null
+++ b/bin/dd/extern.h
@@ -0,0 +1,64 @@
+/* $OpenBSD: extern.h,v 1.9 2014/03/27 15:32:13 tedu Exp $ */
+/* $NetBSD: extern.h,v 1.7 1996/02/20 19:29:07 jtc Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego and Lance
+ * Visser of Convex Computer Corporation.
+ *
+ * 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. 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.
+ *
+ * @(#)extern.h 8.3 (Berkeley) 4/2/94
+ */
+
+void block(void);
+void block_close(void);
+void dd_out(int);
+void def(void);
+void def_close(void);
+void jcl(char **);
+void pos_in(void);
+void pos_out(void);
+void summary(void);
+void summaryx(int);
+void terminate(int);
+void unblock(void);
+void unblock_close(void);
+
+extern IO in, out;
+extern STAT st;
+extern void (*cfunc)(void);
+extern size_t cpy_cnt;
+extern size_t cbsz;
+extern u_int ddflags;
+extern size_t files_cnt;
+extern const u_char *ctab;
+extern const u_char a2e_POSIX[];
+extern const u_char e2a_POSIX[];
+extern const u_char a2ibm_POSIX[];
+extern u_char casetab[];
diff --git a/bin/dd/misc.c b/bin/dd/misc.c
new file mode 100644
index 0000000..4ecb518
--- /dev/null
+++ b/bin/dd/misc.c
@@ -0,0 +1,121 @@
+/* $OpenBSD: misc.c,v 1.18 2014/02/12 01:18:36 bluhm Exp $ */
+/* $NetBSD: misc.c,v 1.4 1995/03/21 09:04:10 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego and Lance
+ * Visser of Convex Computer Corporation.
+ *
+ * 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. 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.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "dd.h"
+#include "extern.h"
+
+void
+summary(void)
+{
+ struct timeval nowtv;
+ char buf[4][100];
+ struct iovec iov[4];
+ double microsecs;
+ int i = 0;
+
+ if (ddflags & C_NOINFO)
+ return;
+
+ (void)gettimeofday(&nowtv, (struct timezone *)NULL);
+ timersub(&nowtv, &st.startv, &nowtv);
+ microsecs = ((double)nowtv.tv_sec * 1000000) + nowtv.tv_usec;
+ if (microsecs == 0)
+ microsecs = 1;
+
+ /* Use snprintf(3) so that we don't reenter stdio(3). */
+ (void)snprintf(buf[0], sizeof(buf[0]),
+ "%zu+%zu records in\n%zu+%zu records out\n",
+ st.in_full, st.in_part, st.out_full, st.out_part);
+ iov[i].iov_base = buf[0];
+ iov[i++].iov_len = strlen(buf[0]);
+
+ if (st.swab) {
+ (void)snprintf(buf[1], sizeof(buf[1]),
+ "%zu odd length swab %s\n",
+ st.swab, (st.swab == 1) ? "block" : "blocks");
+ iov[i].iov_base = buf[1];
+ iov[i++].iov_len = strlen(buf[1]);
+ }
+ if (st.trunc) {
+ (void)snprintf(buf[2], sizeof(buf[2]),
+ "%zu truncated %s\n",
+ st.trunc, (st.trunc == 1) ? "block" : "blocks");
+ iov[i].iov_base = buf[2];
+ iov[i++].iov_len = strlen(buf[2]);
+ }
+ if (!(ddflags & C_NOXFER)) {
+ (void)snprintf(buf[3], sizeof(buf[3]),
+ "%qd bytes transferred in %lld.%03ld secs "
+ "(%0.0f bytes/sec)\n", (long long)st.bytes,
+ (long long)nowtv.tv_sec, nowtv.tv_usec / 1000,
+ ((double)st.bytes * 1000000) / microsecs);
+ iov[i].iov_base = buf[3];
+ iov[i++].iov_len = strlen(buf[3]);
+ }
+
+ (void)writev(STDERR_FILENO, iov, i);
+}
+
+/* ARGSUSED */
+void
+summaryx(int notused)
+{
+ int save_errno = errno;
+
+ summary();
+ errno = save_errno;
+}
+
+/* ARGSUSED */
+void
+terminate(int notused)
+{
+
+ summary();
+ _exit(0);
+}
diff --git a/bin/dd/position.c b/bin/dd/position.c
new file mode 100644
index 0000000..1f0a938
--- /dev/null
+++ b/bin/dd/position.c
@@ -0,0 +1,165 @@
+/* $OpenBSD: position.c,v 1.10 2009/10/27 23:59:21 deraadt Exp $ */
+/* $NetBSD: position.c,v 1.4 1995/03/21 09:04:12 cgd Exp $ */
+
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Keith Muller of the University of California, San Diego and Lance
+ * Visser of Convex Computer Corporation.
+ *
+ * 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. 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.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mtio.h>
+#include <sys/time.h>
+
+#include <err.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "dd.h"
+#include "extern.h"
+
+/*
+ * Position input/output data streams before starting the copy. Device type
+ * dependent. Seekable devices use lseek, and the rest position by reading.
+ * Seeking past the end of file can cause null blocks to be written to the
+ * output.
+ */
+void
+pos_in(void)
+{
+ size_t bcnt;
+ ssize_t nr;
+ off_t cnt;
+ int warned;
+
+ /* If not a pipe, tape or tty device, try to seek on it. */
+ if (!(in.flags & (ISPIPE|ISTAPE)) && !isatty(in.fd)) {
+ if (lseek(in.fd, in.offset * in.dbsz, SEEK_CUR) == -1)
+ err(1, "%s", in.name);
+ return;
+ }
+
+ /*
+ * Read the data. If a pipe, read until satisfy the number of bytes
+ * being skipped. No differentiation for reading complete and partial
+ * blocks for other devices.
+ */
+ for (bcnt = in.dbsz, cnt = in.offset, warned = 0; cnt;) {
+ if ((nr = read(in.fd, in.db, bcnt)) > 0) {
+ if (in.flags & ISPIPE) {
+ if (!(bcnt -= nr)) {
+ bcnt = in.dbsz;
+ --cnt;
+ }
+ } else
+ --cnt;
+ continue;
+ }
+
+ if (nr == 0) {
+ if (files_cnt > 1) {
+ --files_cnt;
+ continue;
+ }
+ errx(1, "skip reached end of input");
+ }
+
+ /*
+ * Input error -- either EOF with no more files, or I/O error.
+ * If noerror not set die. POSIX requires that the warning
+ * message be followed by an I/O display.
+ */
+ if (ddflags & C_NOERROR) {
+ if (!warned) {
+ warn("%s", in.name);
+ warned = 1;
+ summary();
+ }
+ continue;
+ }
+ err(1, "%s", in.name);
+ }
+}
+
+void
+pos_out(void)
+{
+ struct mtop t_op;
+ off_t cnt;
+ ssize_t n;
+
+ /*
+ * If not a tape, try seeking on the file. Seeking on a pipe is
+ * going to fail, but don't protect the user -- they shouldn't
+ * have specified the seek operand.
+ */
+ if (!(out.flags & ISTAPE)) {
+ if (lseek(out.fd, out.offset * out.dbsz, SEEK_SET) == -1)
+ err(1, "%s", out.name);
+ return;
+ }
+
+ /* If no read access, try using mtio. */
+ if (out.flags & NOREAD) {
+ t_op.mt_op = MTFSR;
+ t_op.mt_count = out.offset;
+
+ if (ioctl(out.fd, MTIOCTOP, &t_op) < 0)
+ err(1, "%s", out.name);
+ return;
+ }
+
+ /* Read it. */
+ for (cnt = 0; cnt < out.offset; ++cnt) {
+ if ((n = read(out.fd, out.db, out.dbsz)) > 0)
+ continue;
+
+ if (n < 0)
+ err(1, "%s", out.name);
+
+ /*
+ * If reach EOF, fill with NUL characters; first, back up over
+ * the EOF mark. Note, cnt has not yet been incremented, so
+ * the EOF read does not count as a seek'd block.
+ */
+ t_op.mt_op = MTBSR;
+ t_op.mt_count = 1;
+ if (ioctl(out.fd, MTIOCTOP, &t_op) == -1)
+ err(1, "%s", out.name);
+
+ while (cnt++ < out.offset)
+ if ((n = write(out.fd, out.db, out.dbsz)) != out.dbsz)
+ err(1, "%s", out.name);
+ break;
+ }
+}
diff --git a/bin/df/Makefile b/bin/df/Makefile
new file mode 100644
index 0000000..9c6f241
--- /dev/null
+++ b/bin/df/Makefile
@@ -0,0 +1,8 @@
+# $OpenBSD: Makefile,v 1.8 2003/05/26 18:02:32 ian Exp $
+
+PROG= df
+SRCS= df.c ffs_df.c ext2fs_df.c
+LDADD= -lutil
+DPADD= ${LIBUTIL}
+
+include bsd.prog.mk
diff --git a/bin/df/df.1 b/bin/df/df.1
new file mode 100644
index 0000000..d6383f6
--- /dev/null
+++ b/bin/df/df.1
@@ -0,0 +1,179 @@
+.\" $OpenBSD: df.1,v 1.47 2014/03/17 21:32:12 jmc Exp $
+.\" $NetBSD: df.1,v 1.12 1995/12/05 02:42:45 jtc Exp $
+.\"
+.\" Copyright (c) 1989, 1990, 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. 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.
+.\"
+.\" @(#)df.1 8.2 (Berkeley) 1/13/92
+.\"
+.Dd $Mdocdate: March 17 2014 $
+.Dt DF 1
+.Os
+.Sh NAME
+.Nm df
+.Nd display free disk space
+.Sh SYNOPSIS
+.Nm df
+.Op Fl hiklnP
+.Op Fl t Ar type
+.Oo
+.Op Ar file | file_system
+.Ar ...
+.Oc
+.Sh DESCRIPTION
+The
+.Nm
+utility displays statistics about the amount of free disk space on the
+specified
+.Ar file_system
+or on the file system of which
+.Ar file
+is a part.
+By default, values are displayed as 512-byte block counts.
+If no operands are specified,
+statistics for all mounted file systems are displayed
+(subject to the
+.Fl l
+and
+.Fl t
+options, below).
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl h
+"Human-readable" output.
+Use unit suffixes: Byte, Kilobyte, Megabyte,
+Gigabyte, Terabyte, Petabyte, Exabyte in order to reduce the number of
+digits to four or less.
+This option is incompatible with the
+.Fl P
+option.
+.It Fl i
+Include statistics on the number of free inodes.
+This option is incompatible with the
+.Fl P
+option.
+.It Fl k
+By default, all sizes are reported in 512-byte block counts.
+The
+.Fl k
+option causes the numbers to be reported in kilobyte counts.
+.It Fl l
+Display statistics only about mounted file systems with the
+.Dv MNT_LOCAL
+flag set.
+If a non-local file system is given as an argument, a
+warning is issued and no information is given on that file system.
+.It Fl n
+Print out the previously obtained statistics from the file systems.
+This option should be used if it is possible that one or more
+file systems are in a state such that they will not be able to provide
+statistics without a long delay.
+When this option is specified,
+.Nm
+will not request new statistics from the file systems, but will respond
+with the possibly stale statistics that were previously obtained.
+.It Fl P
+Print out information in a stricter format designed to be parsed
+by portable scripts.
+.It Fl t Ar type
+Indicate the actions should only be taken on
+file systems of the specified
+.Ar type .
+More than one type may be specified in a comma-separated list.
+The list of file system types can be prefixed with
+.Dq no
+to specify the file system types for which action should
+.Em not
+be taken.
+If a file system is given on the command line that is not of
+the specified type, a warning is issued and no information is given on
+that file system.
+.El
+.Pp
+It is not an error to specify more than one of
+the mutually exclusive options
+.Fl h
+and
+.Fl k .
+Where more than one of these options is specified,
+the last option given overrides the others.
+.Sh ENVIRONMENT
+.Bl -tag -width BLOCKSIZE
+.It Ev BLOCKSIZE
+If the environment variable
+.Ev BLOCKSIZE
+is set, and the
+.Fl h
+or
+.Fl k
+options are not specified, the block counts will be displayed in units of that
+size block.
+.El
+.Sh EXIT STATUS
+.Ex -std df
+.Sh EXAMPLES
+Output, in a strict format suitable for portable scripts, disk space
+statistics for the
+.Pa /usr
+file system using kilobyte block sizes:
+.Pp
+.Dl $ df -kP /usr
+.Sh SEE ALSO
+.Xr quota 1 ,
+.Xr getfsstat 2 ,
+.Xr statfs 2 ,
+.Xr getmntinfo 3 ,
+.Xr fstab 5 ,
+.Xr mount 8 ,
+.Xr quot 8
+.Sh STANDARDS
+The
+.Nm
+utility is compliant with the
+.St -p1003.1-2008
+specification.
+.Pp
+The flags
+.Op Fl hiln ,
+as well as the
+.Ev BLOCKSIZE
+environment variable,
+are extensions to that specification.
+.Pp
+This implementation provides the traditional
+.Bx
+.Fl t
+behaviour,
+which differs from the
+X/Open System Interfaces option
+specification.
+.Sh HISTORY
+A
+.Nm
+utility appeared in
+.At v3 .
diff --git a/bin/df/df.c b/bin/df/df.c
new file mode 100644
index 0000000..7eb8fc3
--- /dev/null
+++ b/bin/df/df.c
@@ -0,0 +1,461 @@
+/* $OpenBSD: df.c,v 1.58 2016/03/14 14:44:03 mmcc Exp $ */
+/* $NetBSD: df.c,v 1.21.2.1 1995/11/01 00:06:11 jtc Exp $ */
+
+/*
+ * Copyright (c) 1980, 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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. 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.
+ */
+
+#include <sys/stat.h>
+#include <sys/mount.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <util.h>
+
+int bread(int, off_t, void *, int);
+static void bsdprint(struct statfs *, long, int);
+char *getmntpt(char *);
+static void maketypelist(char *);
+static void posixprint(struct statfs *, long, int);
+static void prthuman(struct statfs *sfsp, unsigned long long);
+static void prthumanval(long long);
+static void prtstat(struct statfs *, int, int, int);
+static long regetmntinfo(struct statfs **, long);
+static int selected(const char *);
+static __dead void usage(void);
+
+extern int e2fs_df(int, char *, struct statfs *);
+extern int ffs_df(int, char *, struct statfs *);
+static int raw_df(char *, struct statfs *);
+
+int hflag, iflag, kflag, lflag, nflag, Pflag;
+char **typelist = NULL;
+
+int
+main(int argc, char *argv[])
+{
+ struct stat stbuf;
+ struct statfs *mntbuf;
+ long mntsize;
+ int ch, i;
+ int width, maxwidth;
+ char *mntpt;
+
+ if (pledge("stdio rpath", NULL) == -1)
+ err(1, "pledge");
+
+ while ((ch = getopt(argc, argv, "hiklnPt:")) != -1)
+ switch (ch) {
+ case 'h':
+ hflag = 1;
+ kflag = 0;
+ break;
+ case 'i':
+ iflag = 1;
+ break;
+ case 'k':
+ kflag = 1;
+ hflag = 0;
+ break;
+ case 'l':
+ lflag = 1;
+ break;
+ case 'n':
+ nflag = 1;
+ break;
+ case 'P':
+ Pflag = 1;
+ break;
+ case 't':
+ if (typelist != NULL)
+ errx(1, "only one -t option may be specified.");
+ maketypelist(optarg);
+ break;
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if ((iflag || hflag) && Pflag) {
+ warnx("-h and -i are incompatible with -P");
+ usage();
+ }
+
+ mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
+ if (mntsize == 0)
+ err(1, "retrieving information on mounted file systems");
+
+ if (!*argv) {
+ mntsize = regetmntinfo(&mntbuf, mntsize);
+ } else {
+ mntbuf = calloc(argc, sizeof(struct statfs));
+ if (mntbuf == NULL)
+ err(1, NULL);
+ mntsize = 0;
+ for (; *argv; argv++) {
+ if (stat(*argv, &stbuf) < 0) {
+ if ((mntpt = getmntpt(*argv)) == 0) {
+ warn("%s", *argv);
+ continue;
+ }
+ } else if (S_ISCHR(stbuf.st_mode) || S_ISBLK(stbuf.st_mode)) {
+ if (!raw_df(*argv, &mntbuf[mntsize]))
+ ++mntsize;
+ continue;
+ } else
+ mntpt = *argv;
+ /*
+ * Statfs does not take a `wait' flag, so we cannot
+ * implement nflag here.
+ */
+ if (!statfs(mntpt, &mntbuf[mntsize]))
+ if (lflag && (mntbuf[mntsize].f_flags & MNT_LOCAL) == 0)
+ warnx("%s is not a local file system",
+ *argv);
+ else if (!selected(mntbuf[mntsize].f_fstypename))
+ warnx("%s mounted as a %s file system",
+ *argv, mntbuf[mntsize].f_fstypename);
+ else
+ ++mntsize;
+ else
+ warn("%s", *argv);
+ }
+ }
+
+ if (mntsize) {
+ maxwidth = 11;
+ for (i = 0; i < mntsize; i++) {
+ width = strlen(mntbuf[i].f_mntfromname);
+ if (width > maxwidth)
+ maxwidth = width;
+ }
+
+ if (Pflag)
+ posixprint(mntbuf, mntsize, maxwidth);
+ else
+ bsdprint(mntbuf, mntsize, maxwidth);
+ }
+
+ return (mntsize ? 0 : 1);
+}
+
+char *
+getmntpt(char *name)
+{
+ long mntsize, i;
+ struct statfs *mntbuf;
+
+ mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
+ for (i = 0; i < mntsize; i++) {
+ if (!strcmp(mntbuf[i].f_mntfromname, name))
+ return (mntbuf[i].f_mntonname);
+ }
+ return (0);
+}
+
+static enum { IN_LIST, NOT_IN_LIST } which;
+
+static int
+selected(const char *type)
+{
+ char **av;
+
+ /* If no type specified, it's always selected. */
+ if (typelist == NULL)
+ return (1);
+ for (av = typelist; *av != NULL; ++av)
+ if (!strncmp(type, *av, MFSNAMELEN))
+ return (which == IN_LIST ? 1 : 0);
+ return (which == IN_LIST ? 0 : 1);
+}
+
+static void
+maketypelist(char *fslist)
+{
+ int i;
+ char *nextcp, **av;
+
+ if ((fslist == NULL) || (fslist[0] == '\0'))
+ errx(1, "empty type list");
+
+ /*
+ * XXX
+ * Note: the syntax is "noxxx,yyy" for no xxx's and
+ * no yyy's, not the more intuitive "noyyy,noyyy".
+ */
+ if (fslist[0] == 'n' && fslist[1] == 'o') {
+ fslist += 2;
+ which = NOT_IN_LIST;
+ } else
+ which = IN_LIST;
+
+ /* Count the number of types. */
+ for (i = 1, nextcp = fslist; (nextcp = strchr(nextcp, ',')) != NULL; i++)
+ ++nextcp;
+
+ /* Build an array of that many types. */
+ if ((av = typelist = calloc(i + 1, sizeof(char *))) == NULL)
+ err(1, NULL);
+ av[0] = fslist;
+ for (i = 1, nextcp = fslist; (nextcp = strchr(nextcp, ',')) != NULL; i++) {
+ *nextcp = '\0';
+ av[i] = ++nextcp;
+ }
+ /* Terminate the array. */
+ av[i] = NULL;
+}
+
+/*
+ * Make a pass over the filesystem info in ``mntbuf'' filtering out
+ * filesystem types not in ``fsmask'' and possibly re-stating to get
+ * current (not cached) info. Returns the new count of valid statfs bufs.
+ */
+static long
+regetmntinfo(struct statfs **mntbufp, long mntsize)
+{
+ int i, j;
+ struct statfs *mntbuf;
+
+ if (!lflag && typelist == NULL)
+ return (nflag ? mntsize : getmntinfo(mntbufp, MNT_WAIT));
+
+ mntbuf = *mntbufp;
+ j = 0;
+ for (i = 0; i < mntsize; i++) {
+ if (lflag && (mntbuf[i].f_flags & MNT_LOCAL) == 0)
+ continue;
+ if (!selected(mntbuf[i].f_fstypename))
+ continue;
+ if (nflag)
+ mntbuf[j] = mntbuf[i];
+ else
+ (void)statfs(mntbuf[i].f_mntonname, &mntbuf[j]);
+ j++;
+ }
+ return (j);
+}
+
+/*
+ * "human-readable" output: use 3 digits max.--put unit suffixes at
+ * the end. Makes output compact and easy-to-read esp. on huge disks.
+ * Code moved into libutil; this is now just a wrapper.
+ */
+static void
+prthumanval(long long bytes)
+{
+ char ret[FMT_SCALED_STRSIZE];
+
+ if (fmt_scaled(bytes, ret) == -1) {
+ (void)printf(" %lld", bytes);
+ return;
+ }
+ (void)printf(" %7s", ret);
+}
+
+static void
+prthuman(struct statfs *sfsp, unsigned long long used)
+{
+ prthumanval(sfsp->f_blocks * sfsp->f_bsize);
+ prthumanval(used * sfsp->f_bsize);
+ prthumanval(sfsp->f_bavail * sfsp->f_bsize);
+}
+
+/*
+ * Convert statfs returned filesystem size into BLOCKSIZE units.
+ * Attempts to avoid overflow for large filesystems.
+ */
+#define fsbtoblk(num, fsbs, bs) \
+ (((fsbs) != 0 && (fsbs) < (bs)) ? \
+ (num) / ((bs) / (fsbs)) : (num) * ((fsbs) / (bs)))
+
+/*
+ * Print out status about a filesystem.
+ */
+static void
+prtstat(struct statfs *sfsp, int maxwidth, int headerlen, int blocksize)
+{
+ u_int64_t used, inodes;
+ int64_t availblks;
+
+ (void)printf("%-*.*s", maxwidth, maxwidth, sfsp->f_mntfromname);
+ used = sfsp->f_blocks - sfsp->f_bfree;
+ availblks = sfsp->f_bavail + used;
+ if (hflag)
+ prthuman(sfsp, used);
+ else
+ (void)printf(" %*llu %9llu %9lld", headerlen,
+ fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize),
+ fsbtoblk(used, sfsp->f_bsize, blocksize),
+ fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize));
+ (void)printf(" %5.0f%%",
+ availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0);
+ if (iflag) {
+ inodes = sfsp->f_files;
+ used = inodes - sfsp->f_ffree;
+ (void)printf(" %7llu %7llu %5.0f%% ", used, sfsp->f_ffree,
+ inodes == 0 ? 100.0 : (double)used / (double)inodes * 100.0);
+ } else
+ (void)printf(" ");
+ (void)printf(" %s\n", sfsp->f_mntonname);
+}
+
+/*
+ * Print in traditional BSD format.
+ */
+static void
+bsdprint(struct statfs *mntbuf, long mntsize, int maxwidth)
+{
+ int i;
+ char *header;
+ int headerlen;
+ long blocksize;
+
+ /* Print the header line */
+ if (hflag) {
+ header = " Size";
+ headerlen = strlen(header);
+ (void)printf("%-*.*s %s Used Avail Capacity",
+ maxwidth, maxwidth, "Filesystem", header);
+ } else {
+ if (kflag) {
+ blocksize = 1024;
+ header = "1K-blocks";
+ headerlen = strlen(header);
+ } else
+ header = getbsize(&headerlen, &blocksize);
+ (void)printf("%-*.*s %s Used Avail Capacity",
+ maxwidth, maxwidth, "Filesystem", header);
+ }
+ if (iflag)
+ (void)printf(" iused ifree %%iused");
+ (void)printf(" Mounted on\n");
+
+
+ for (i = 0; i < mntsize; i++)
+ prtstat(&mntbuf[i], maxwidth, headerlen, blocksize);
+ return;
+}
+
+/*
+ * Print in format defined by POSIX 1002.2, invoke with -P option.
+ */
+static void
+posixprint(struct statfs *mntbuf, long mntsize, int maxwidth)
+{
+ int i;
+ int blocksize;
+ char *blockstr;
+ struct statfs *sfsp;
+ long long used, avail;
+ double percentused;
+
+ if (kflag) {
+ blocksize = 1024;
+ blockstr = "1024-blocks";
+ } else {
+ blocksize = 512;
+ blockstr = " 512-blocks";
+ }
+
+ (void)printf(
+ "%-*.*s %s Used Available Capacity Mounted on\n",
+ maxwidth, maxwidth, "Filesystem", blockstr);
+
+ for (i = 0; i < mntsize; i++) {
+ sfsp = &mntbuf[i];
+ used = sfsp->f_blocks - sfsp->f_bfree;
+ avail = sfsp->f_bavail + used;
+ if (avail == 0)
+ percentused = 100.0;
+ else
+ percentused = (double)used / (double)avail * 100.0;
+
+ (void) printf ("%-*.*s %*lld %10lld %11lld %5.0f%% %s\n",
+ maxwidth, maxwidth, sfsp->f_mntfromname,
+ (int)strlen(blockstr),
+ fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize),
+ fsbtoblk(used, sfsp->f_bsize, blocksize),
+ fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize),
+ percentused, sfsp->f_mntonname);
+ }
+}
+
+static int
+raw_df(char *file, struct statfs *sfsp)
+{
+ int rfd, ret = -1;
+
+ if ((rfd = open(file, O_RDONLY)) < 0) {
+ warn("%s", file);
+ return (-1);
+ }
+
+ if (ffs_df(rfd, file, sfsp) == 0) {
+ ret = 0;
+ } else if (e2fs_df(rfd, file, sfsp) == 0) {
+ ret = 0;
+ }
+
+ close (rfd);
+ return (ret);
+}
+
+int
+bread(int rfd, off_t off, void *buf, int cnt)
+{
+ int nr;
+
+ if ((nr = pread(rfd, buf, cnt, off)) != cnt) {
+ /* Probably a dismounted disk if errno == EIO. */
+ if (errno != EIO)
+ (void)fprintf(stderr, "\ndf: %qd: %s\n",
+ off, strerror(nr > 0 ? EIO : errno));
+ return (0);
+ }
+ return (1);
+}
+
+static __dead void
+usage(void)
+{
+ (void)fprintf(stderr,
+ "usage: %s [-hiklnP] [-t type] [[file | file_system] ...]\n",
+ getprogname());
+ exit(1);
+}
diff --git a/bin/df/ext2fs_df.c b/bin/df/ext2fs_df.c
new file mode 100644
index 0000000..f362235
--- /dev/null
+++ b/bin/df/ext2fs_df.c
@@ -0,0 +1,103 @@
+/* $OpenBSD: ext2fs_df.c,v 1.16 2016/03/01 17:57:49 mmcc Exp $ */
+
+/*
+ * This file is substantially derived from src/sys/ufs/ext2fs/ext2fs_vfsops.c:e2fs_statfs().
+ * That file's copyright is applied here.
+ */
+
+/* Modified for EXT2FS on NetBSD by Manuel Bouyer, April 1997 */
+
+/*
+ * Copyright (c) 1989, 1991, 1993, 1994
+ * 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. 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.
+ *
+ * @(#)ffs_vfsops.c 8.14 (Berkeley) 11/28/94
+ */
+
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <ufs/ext2fs/ext2fs.h>
+#include <ufs/ext2fs/ext2fs_dinode.h>
+#include <string.h>
+
+int e2fs_df(int, char *, struct statfs *);
+
+extern int bread(int, off_t, void *, int);
+extern char *getmntpt(char *);
+
+static union {
+ struct ext2fs ie_fs;
+ char dummy[SBSIZE];
+} sb;
+#define sblock sb.ie_fs
+
+int
+e2fs_df(int rfd, char *file, struct statfs *sfsp)
+{
+ char *mntpt;
+ u_int32_t overhead, overhead_per_group;
+ int32_t ncg, ngdb, ipb, itpg;
+
+ if (bread(rfd, (off_t)SBOFF, &sblock, SBSIZE) == 0) {
+ return (-1);
+ }
+ if ((sblock.e2fs_magic != E2FS_MAGIC) ||
+ (sblock.e2fs_rev != E2FS_REV0 && sblock.e2fs_rev != E2FS_REV1)) {
+ return (-1);
+ }
+ sfsp->f_flags = 0; /* The fs is not mapped, so no flags */
+ sfsp->f_bsize = 1024 << sblock.e2fs_log_bsize;
+ sfsp->f_iosize = 1024 << sblock.e2fs_log_bsize;
+
+ if ((ipb = sfsp->f_bsize / sizeof(struct ext2fs_dinode)) == 0)
+ return (-1);
+ itpg = sblock.e2fs_ipg / ipb;
+
+ ncg = howmany(sblock.e2fs_bcount - sblock.e2fs_first_dblock,
+ sblock.e2fs_bpg);
+ ngdb = howmany(ncg, sfsp->f_bsize / sizeof(struct ext2_gd));
+ overhead_per_group = 1 /* super block */ +
+ ngdb +
+ 1 /* block bitmap */ +
+ 1 /* inode bitmap */ +
+ itpg;
+ overhead = sblock.e2fs_first_dblock + ncg * overhead_per_group;
+
+ sfsp->f_blocks = sblock.e2fs_bcount - overhead;
+ sfsp->f_bfree = sblock.e2fs_fbcount;
+ sfsp->f_bavail = sfsp->f_bfree - sblock.e2fs_rbcount;
+ sfsp->f_files = sblock.e2fs_icount;
+ sfsp->f_ffree = sblock.e2fs_ficount;
+ sfsp->f_fsid.val[0] = 0;
+ sfsp->f_fsid.val[1] = 0;
+ if ((mntpt = getmntpt(file)) == 0)
+ mntpt = "";
+ strlcpy(sfsp->f_mntonname, mntpt, sizeof(sfsp->f_mntonname));
+ strlcpy(sfsp->f_mntfromname, file, sizeof(sfsp->f_mntfromname));
+ strlcpy(sfsp->f_fstypename, MOUNT_EXT2FS, sizeof(sfsp->f_fstypename));
+ return (0);
+}
diff --git a/bin/df/ffs_df.c b/bin/df/ffs_df.c
new file mode 100644
index 0000000..b23301e
--- /dev/null
+++ b/bin/df/ffs_df.c
@@ -0,0 +1,95 @@
+/* $OpenBSD: ffs_df.c,v 1.19 2016/03/01 17:57:49 mmcc Exp $ */
+
+/*
+ * Copyright (c) 1980, 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * 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. 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.
+ */
+
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <ufs/ffs/fs.h>
+#include <ufs/ufs/dinode.h>
+
+#include <string.h>
+
+int ffs_df(int, char *, struct statfs *);
+
+extern int bread(int, off_t, void *, int);
+extern char *getmntpt(char *);
+
+static union {
+ struct fs iu_fs;
+ char dummy[SBSIZE];
+} sb;
+#define sblock sb.iu_fs
+
+int
+ffs_df(int rfd, char *file, struct statfs *sfsp)
+{
+ char *mntpt;
+
+ if (!((bread(rfd, (off_t)SBLOCK_UFS1, &sblock, SBSIZE) == 1 &&
+ sblock.fs_magic == FS_UFS1_MAGIC) ||
+ (bread(rfd, (off_t)SBLOCK_UFS2, &sblock, SBSIZE) == 1 &&
+ sblock.fs_magic == FS_UFS2_MAGIC))) {
+ return (-1);
+ }
+
+ sfsp->f_flags = 0;
+ sfsp->f_bsize = sblock.fs_fsize;
+ sfsp->f_iosize = sblock.fs_bsize;
+ if (sblock.fs_magic == FS_UFS1_MAGIC) {
+ sfsp->f_blocks = sblock.fs_ffs1_dsize;
+ sfsp->f_bfree = sblock.fs_ffs1_cstotal.cs_nbfree *
+ sblock.fs_frag + sblock.fs_ffs1_cstotal.cs_nffree;
+ sfsp->f_bavail = sfsp->f_bfree -
+ ((int64_t)sblock.fs_ffs1_dsize * sblock.fs_minfree / 100);
+ sfsp->f_files = sblock.fs_ncg * sblock.fs_ipg - ROOTINO;
+ sfsp->f_ffree = sblock.fs_ffs1_cstotal.cs_nifree;
+ } else {
+ sfsp->f_blocks = sblock.fs_dsize;
+ sfsp->f_bfree = sblock.fs_cstotal.cs_nbfree *
+ sblock.fs_frag + sblock.fs_cstotal.cs_nffree;
+ sfsp->f_bavail = sfsp->f_bfree -
+ ((int64_t)sblock.fs_dsize * sblock.fs_minfree / 100);
+ sfsp->f_files = sblock.fs_ncg * sblock.fs_ipg - ROOTINO;
+ sfsp->f_ffree = sblock.fs_cstotal.cs_nifree;
+ }
+ sfsp->f_fsid.val[0] = 0;
+ sfsp->f_fsid.val[1] = 0;
+ if ((mntpt = getmntpt(file)) == 0)
+ mntpt = "";
+ strlcpy(sfsp->f_mntonname, mntpt, sizeof(sfsp->f_mntonname));
+ strlcpy(sfsp->f_mntfromname, file, sizeof(sfsp->f_mntfromname));
+ strlcpy(sfsp->f_fstypename, MOUNT_EXT2FS, sizeof(sfsp->f_fstypename));
+ return (0);
+}
diff --git a/bin/domainname/Makefile b/bin/domainname/Makefile
new file mode 100644
index 0000000..90ac043
--- /dev/null
+++ b/bin/domainname/Makefile
@@ -0,0 +1,5 @@
+# $OpenBSD: Makefile,v 1.3 1997/09/21 11:34:59 deraadt Exp $
+
+PROG= domainname
+
+include bsd.prog.mk
diff --git a/bin/domainname/domainname.1 b/bin/domainname/domainname.1
new file mode 100644
index 0000000..31039aa
--- /dev/null
+++ b/bin/domainname/domainname.1
@@ -0,0 +1,70 @@
+.\" $OpenBSD: domainname.1,v 1.18 2012/05/27 07:10:15 jmc Exp $
+.\" $NetBSD: domainname.1,v 1.7 1995/07/25 19:36:57 jtc Exp $
+.\"
+.\" Copyright (c) 1983, 1988, 1990, 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. 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.
+.\"
+.\" @(#)hostname.1 8.1 (Berkeley) 5/31/93
+.\"
+.Dd $Mdocdate: May 27 2012 $
+.Dt DOMAINNAME 1
+.Os
+.Sh NAME
+.Nm domainname
+.Nd set or print YP domain of current host system
+.Sh SYNOPSIS
+.Nm domainname
+.Op Ar name-of-domain
+.Sh DESCRIPTION
+The
+.Nm
+utility prints the YP domain name of the current host.
+The superuser can set the domain name by supplying a
+.Pa /etc/defaultdomain
+file (see
+.Xr defaultdomain 5 ) .
+This is used at system boot time by
+.Xr rc 8
+to initialize the domainname.
+.Sh SEE ALSO
+.Xr hostname 1 ,
+.Xr getdomainname 3 ,
+.Xr setdomainname 3 ,
+.Xr defaultdomain 5 ,
+.Xr rc 8 ,
+.Xr yp 8
+.Sh HISTORY
+The
+.Nm
+utility is derived from the
+.Xr hostname 1
+utility, which appeared in
+.Bx 4.2 .
+The
+.Nm
+utility appeared in
+.Nx 0.8 .
diff --git a/bin/domainname/domainname.c b/bin/domainname/domainname.c
new file mode 100644
index 0000000..008e7e4
--- /dev/null
+++ b/bin/domainname/domainname.c
@@ -0,0 +1,77 @@
+/* $OpenBSD: domainname.c,v 1.10 2016/02/01 22:26:39 gsoares Exp $ */
+/* $NetBSD: domainname.c,v 1.7 1995/03/21 09:04:22 cgd Exp $ */
+
+/*
+ * Copyright (c) 1988, 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. 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.
+ */
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+
+extern char *__progname;
+
+static void __dead usage(void);
+
+int
+main(int argc, char *argv[])
+{
+ int ch;
+ char domainname[HOST_NAME_MAX+1];
+
+ while ((ch = getopt(argc, argv, "")) != -1)
+ switch (ch) {
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 1)
+ usage();
+
+ if (*argv) {
+ if (setdomainname(*argv, strlen(*argv)))
+ err(1, "setdomainname");
+ } else {
+ if (getdomainname(domainname, sizeof(domainname)))
+ err(1, "getdomainname");
+ (void)printf("%s\n", domainname);
+ }
+ return(0);
+}
+
+static void __dead
+usage(void)
+{
+ (void)fprintf(stderr, "usage: %s [name-of-domain]\n", __progname);
+ exit(1);
+}
diff --git a/bin/echo/Makefile b/bin/echo/Makefile
new file mode 100644
index 0000000..5fbe97f
--- /dev/null
+++ b/bin/echo/Makefile
@@ -0,0 +1,5 @@
+# $OpenBSD: Makefile,v 1.3 1997/09/21 11:35:02 deraadt Exp $
+
+PROG= echo
+
+include bsd.prog.mk
diff --git a/bin/echo/echo.1 b/bin/echo/echo.1
new file mode 100644
index 0000000..6ed31de
--- /dev/null
+++ b/bin/echo/echo.1
@@ -0,0 +1,100 @@
+.\" $OpenBSD: echo.1,v 1.22 2014/02/15 09:57:31 jmc Exp $
+.\" $NetBSD: echo.1,v 1.7 1995/03/21 09:04:26 cgd Exp $
+.\"
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the Institute of Electrical and Electronics Engineers, Inc.
+.\"
+.\" 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. 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.
+.\"
+.\" @(#)echo.1 8.1 (Berkeley) 7/22/93
+.\"
+.Dd $Mdocdate: February 15 2014 $
+.Dt ECHO 1
+.Os
+.Sh NAME
+.Nm echo
+.Nd write arguments to the standard output
+.Sh SYNOPSIS
+.Nm echo
+.Op Fl n
+.Op Ar string ...
+.Sh DESCRIPTION
+The
+.Nm
+utility writes any specified operands, separated by single blank
+.Pq Sq \ \&
+characters and followed by a newline
+.Pq Sq \en
+character, to the standard
+output.
+.Pp
+When no operands are given, only the newline is written.
+The -- operand,
+which generally denotes an end to option processing,
+is treated as part of
+.Ar string .
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl n
+Do not print the trailing newline character.
+.El
+.Sh EXIT STATUS
+.Ex -std echo
+.Sh SEE ALSO
+.Xr csh 1 ,
+.Xr ksh 1 ,
+.Xr printf 1
+.Sh STANDARDS
+The
+.Nm
+utility is compliant with the
+.St -p1003.1-2008
+specification.
+.Pp
+The flag
+.Op Fl n
+conflicts with the behaviour mandated by the
+X/Open System Interfaces option of the
+.St -p1003.1-2008
+specification,
+which says it should be treated as part of
+.Ar string .
+Additionally,
+.Nm
+does not support any of the backslash character sequences mandated by XSI.
+.Pp
+.Nm
+also exists as a built-in to
+.Xr csh 1
+and
+.Xr ksh 1 ,
+though with a different syntax.
+.Pp
+Where portability is paramount, use
+.Xr printf 1 .
diff --git a/bin/echo/echo.c b/bin/echo/echo.c
new file mode 100644
index 0000000..7a5d38c
--- /dev/null
+++ b/bin/echo/echo.c
@@ -0,0 +1,64 @@
+/* $OpenBSD: echo.c,v 1.10 2015/10/09 01:37:06 deraadt Exp $ */
+/* $NetBSD: echo.c,v 1.6 1995/03/21 09:04:27 cgd Exp $ */
+
+/*
+ * Copyright (c) 1989, 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. 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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <err.h>
+
+/* ARGSUSED */
+int
+main(int argc, char *argv[])
+{
+ int nflag;
+
+ if (pledge("stdio", NULL) == -1)
+ err(1, "pledge");
+
+ /* This utility may NOT do getopt(3) option parsing. */
+ if (*++argv && !strcmp(*argv, "-n")) {
+ ++argv;
+ nflag = 1;
+ }
+ else
+ nflag = 0;
+
+ while (*argv) {
+ (void)fputs(*argv, stdout);
+ if (*++argv)
+ putchar(' ');
+ }
+ if (!nflag)
+ putchar('\n');
+
+ return 0;
+}
diff --git a/bin/ed/Makefile b/bin/ed/Makefile
new file mode 100644
index 0000000..9e2439b
--- /dev/null
+++ b/bin/ed/Makefile
@@ -0,0 +1,7 @@
+# $OpenBSD: Makefile,v 1.11 2014/05/24 01:35:55 daniel Exp $
+
+PROG= ed
+CFLAGS+=-DBACKWARDS
+SRCS= buf.c glbl.c io.c main.c re.c sub.c undo.c
+
+include bsd.prog.mk
diff --git a/bin/ed/POSIX b/bin/ed/POSIX
new file mode 100644
index 0000000..1cd2afc
--- /dev/null
+++ b/bin/ed/POSIX
@@ -0,0 +1,91 @@
+$OpenBSD: POSIX,v 1.8 2014/05/24 01:35:55 daniel Exp $
+$NetBSD: POSIX,v 1.9 1995/03/21 09:04:32 cgd Exp $
+
+This version of ed(1) is not strictly POSIX compliant, as described in
+the POSIX 1003.2 document. The following is a summary of the omissions,
+extensions and possible deviations from POSIX 1003.2.
+
+OMISSIONS
+---------
+1) Locale(3) is not supported yet.
+
+2) For backwards compatibility, the POSIX rule that says a range of
+ addresses cannot be used where only a single address is expected has
+ been relaxed.
+
+3) To support the BSD `s' command (see extension [1] below),
+ substitution patterns cannot be delimited by numbers or the characters
+ `r', `g' and `p'. In contrast, POSIX specifies any character except
+ space or newline can be used as a delimiter.
+
+EXTENSIONS
+----------
+1) BSD commands have been implemented wherever they do not conflict with
+ the POSIX standard. The BSD-ism's included are:
+ i) `s' (i.e., s[n][rgp]*) to repeat a previous substitution,
+ ii) `W' for appending text to an existing file,
+ iii) `wq' for exiting after a write,
+ iv) `z' for scrolling through the buffer, and
+ v) BSD line addressing syntax (i.e., `^' and `%') is recognized.
+
+2) The POSIX interactive global commands `G' and `V' are extended to
+ support multiple commands, including `a', `i' and `c'. The command
+ format is the same as for the global commands `g' and `v', i.e., one
+ command per line with each line, except for the last, ending in a
+ backslash (\).
+
+3) An extension to the POSIX file commands `E', `e', `r', `W' and `w' is
+ that <file> arguments are processed for backslash escapes, i.e., any
+ character preceded by a backslash is interpreted literally. If the
+ first unescaped character of a <file> argument is a bang (!), then the
+ rest of the line is interpreted as a shell command, and no escape
+ processing is performed by ed.
+
+DEVIATIONS
+----------
+1) Though ed is not a stream editor, it can be used to edit binary files.
+ To assist in binary editing, when a file containing at least one ASCII
+ NUL character is written, a newline is not appended if it did not
+ already contain one upon reading. In particular, reading /dev/null
+ prior to writing prevents appending a newline to a binary file.
+
+ For example, to create a file with ed containing a single NUL character:
+ $ ed file
+ a
+ ^@
+ .
+ r /dev/null
+ wq
+
+ Similarly, to remove a newline from the end of binary `file':
+ $ ed file
+ r /dev/null
+ wq
+
+2) Since the behavior of `u' (undo) within a `g' (global) command list is
+ not specified by POSIX, it follows the behavior of the SunOS ed:
+ undo forces a global command list to be executed only once, rather than
+ for each line matching a global pattern. In addition, each instance of
+ `u' within a global command undoes all previous commands (including
+ undo's) in the command list. This seems the best way, since the
+ alternatives are either too complicated to implement or too confusing
+ to use.
+
+ The global/undo combination is useful for masking errors that
+ would otherwise cause a script to fail. For instance, an ed script
+ to remove any occurrences of either `censor1' or `censor2' might be
+ written as:
+ ed - file <<EOF
+ 1g/.*/u\
+ ,s/censor1//g\
+ ,s/censor2//g
+ ...
+
+3) The `m' (move) command within a `g' command list also follows the SunOS
+ ed implementation: any moved lines are removed from the global command's
+ `active' list.
+
+4) If ed is invoked with a name argument prefixed by a bang (!), then the
+ remainder of the argument is interpreted as a shell command. To invoke
+ ed on a file whose name starts with bang, prefix the name with a
+ backslash.
diff --git a/bin/ed/README b/bin/ed/README
new file mode 100644
index 0000000..7a5ac50
--- /dev/null
+++ b/bin/ed/README
@@ -0,0 +1,22 @@
+$OpenBSD: README,v 1.4 2014/04/20 09:29:36 deraadt Exp $
+$NetBSD: README,v 1.9 1995/03/21 09:04:33 cgd Exp $
+
+ed is an 8-bit-clean, POSIX-compliant line editor. It should work with
+any regular expression package that conforms to the POSIX interface
+standard, such as GNU regex(3).
+
+If reliable signals are supported (e.g., POSIX sigaction(2)), it should
+compile with little trouble. Otherwise, the macros SPL1() and SPL0()
+should be redefined to disable interrupts.
+
+The following compiler directive is recognized:
+BACKWARDS - for backwards compatibility
+
+The file `POSIX' describes extensions to and deviations from the POSIX
+standard.
+
+The ./test directory contains regression tests for ed. The README
+file in that directory explains how to run these.
+
+For a description of the ed algorithm, see Kernighan and Plauger's book
+"Software Tools in Pascal," Addison-Wesley, 1981.
diff --git a/bin/ed/USD.doc/09.edtut/Makefile b/bin/ed/USD.doc/09.edtut/Makefile
new file mode 100644
index 0000000..0fac239
--- /dev/null
+++ b/bin/ed/USD.doc/09.edtut/Makefile
@@ -0,0 +1,10 @@
+# $OpenBSD: Makefile,v 1.2 2004/02/01 15:21:55 jmc Exp $
+
+DIR= usd/09.edtut
+SRCS= e.mac e0 e1 e2 e3 e4 e5 e6 e7
+MACROS= -ms
+
+paper.txt: ${SRCS}
+ ${ROFF} -Tascii ${SRCS} > ${.TARGET}
+
+include bsd.doc.mk
diff --git a/bin/ed/USD.doc/09.edtut/e.mac b/bin/ed/USD.doc/09.edtut/e.mac
new file mode 100644
index 0000000..39624ba
--- /dev/null
+++ b/bin/ed/USD.doc/09.edtut/e.mac
@@ -0,0 +1,72 @@
+.\" $OpenBSD: e.mac,v 1.3 2004/04/05 16:06:01 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)e.mac 8.1 (Berkeley) 8/14/93
+.\"
+.ds . \&\s+2.\s0\&
+.de UC
+\&\\$3\s-1\\$1\s0\\$2
+..
+.de UL
+\&\\$3\f2\\$1\f1\\$2
+..
+.de IT
+\&\\$3\f2\\$1\fP\\$2
+..
+.de UI
+\f3\\$1\fI\\$2\fR\\$3
+..
+.de P1
+.if n .ls 1
+.nf
+.if n .ta 5 10 15 20 25 30 35 40 45 50 55 60
+.if t .ta .3i .6i .9i 1.2i 1.5i 1.8i
+.tr -\-
+.\" use first argument as indent if present
+.if \\n(.$ .DS I \\$1
+.if !\\n(.$ .DS I 5
+.bd 1 2
+..
+.de P2
+.br
+.bd 1 2
+.DE
+.bd 1
+.tr --
+.if n .ls 1
+..
+.hy 14
+.\" 2=not last lines; 4= no -xx; 8=no xx-
+.tr *\(**
+.nr PI .2i
diff --git a/bin/ed/USD.doc/09.edtut/e0 b/bin/ed/USD.doc/09.edtut/e0
new file mode 100644
index 0000000..f85668d
--- /dev/null
+++ b/bin/ed/USD.doc/09.edtut/e0
@@ -0,0 +1,74 @@
+.\" $OpenBSD: e0,v 1.3 2004/04/05 10:58:08 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)e0 8.1 (Berkeley) 8/14/93
+.\"
+.if n \{\
+.po 5n
+.ll 70n
+.\}
+.EH 'USD:9-%''A Tutorial Introduction to the \s-2UNIX\s+2 Text Editor'
+.OH 'A Tutorial Introduction to the \s-2UNIX\s+2 Text Editor''USD:9-%'
+.\".RP
+.TL
+A Tutorial Introduction to the \s-2UNIX\s+2 Text Editor
+.AU
+Brian W. Kernighan
+.AI
+Murray Hill, NJ
+.AB
+.PP
+Almost all text input on
+the
+.UX
+operating system
+is done with
+the text-editor
+.IT ed .
+This memorandum is a tutorial guide
+to help beginners get started
+with text editing.
+.PP
+Although it does not cover everything,
+it does discuss enough for most users'
+day-to-day needs.
+This includes
+printing, appending, changing, deleting, moving,
+and inserting entire lines of text;
+reading and writing files;
+context searching and line addressing;
+the substitute command;
+the global commands;
+and the use of special characters for advanced editing.
+.AE
diff --git a/bin/ed/USD.doc/09.edtut/e1 b/bin/ed/USD.doc/09.edtut/e1
new file mode 100644
index 0000000..8691f0e
--- /dev/null
+++ b/bin/ed/USD.doc/09.edtut/e1
@@ -0,0 +1,271 @@
+.\" $OpenBSD: e1,v 1.4 2004/04/05 10:58:08 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)e1 8.1 (Berkeley) 6/8/93
+.\"
+.nr PS 9
+.nr VS 11
+.SH
+Introduction
+.PP
+.ul
+Ed
+is a ``text editor'', that is, an interactive program
+for creating and modifying ``text'',
+using directions provided by a user at
+a terminal.
+The text is often a document
+like this one,
+or a program,
+or perhaps data for a program.
+.PP
+This introduction is meant to simplify learning
+.UL ed .
+The recommended way to learn
+.ul
+ed
+is to read this document,
+simultaneously using
+.ul
+ed
+to follow the examples,
+then to read the description in section I of the
+.ul
+.UC UNIX
+.UL "Programmer's Manual" ,
+all the while
+experimenting with
+.UL ed .
+(Solicitation of advice from experienced users is also useful.)
+.PP
+Do the exercises!
+They cover material not completely discussed
+in the actual text.
+An appendix summarizes the commands.
+.SH
+Disclaimer
+.PP
+This is an introduction and a tutorial.
+For this reason, no attempt is made to
+cover more than a part of the facilities that
+.ul
+ed
+offers
+(although this fraction includes the most useful and frequently used
+parts).
+When you have mastered the Tutorial,
+try
+.ul
+Advanced Editing on
+.ul
+.UC UNIX .
+Also,
+there is not enough space to explain basic
+.UC UNIX
+procedures.
+We will assume that you know how to log on to
+.UC UNIX ,
+and that you have at least a vague understanding
+of what a file is.
+For more on that, read
+.ul
+.UC UNIX
+.UL "for Beginners" .
+.PP
+You must also know what character to type as the end-of-line
+on your particular terminal.
+This character is the
+.UC RETURN
+key on most terminals.
+Throughout, we will refer to this character,
+whatever it is,
+as
+.UC RETURN .
+.SH
+Getting Started
+.PP
+We'll assume that you have logged in to
+your system
+and it has just printed the prompt character,
+usually either a
+.UL $
+or a
+.UL % .
+The
+easiest way to get
+.ul
+ed
+is to type
+.P1
+ed (followed by a return)
+.P2
+You are now ready to go \-
+.ul
+ed
+is waiting for you to tell it what to do.
+.SH
+Creating Text \- the Append command ``a''
+.PP
+As your first problem, suppose you want to create some text
+starting from scratch.
+Perhaps you are typing the very first
+draft of a paper; clearly it will have to start
+somewhere, and undergo modifications later.
+This section will show how to get some text in, just to
+get started.
+Later we'll talk about how to change it.
+.PP
+When
+.ul
+ed
+is first started, it is rather like working
+with a blank piece of paper \- there is no text
+or information present.
+This must be supplied by the person using
+.UL ed ;
+it is usually done
+by typing in the text, or by reading it into
+.ul
+ed
+from a
+file.
+We will start by typing in some text, and return shortly to how to
+read files.
+.PP
+First a bit of terminology.
+In
+.ul
+ed
+jargon, the text being
+worked on is said to be ``kept in a buffer.''
+Think of the
+buffer as a work space, if you like, or simply as the information
+that you are going to be editing.
+In effect the buffer is like the
+piece of paper, on which we will write things, then change some
+of them, and finally file the whole thing away for another day.
+.PP
+The user tells
+.ul
+ed
+what to do to his text
+by typing instructions called ``commands.''
+Most
+commands consist of a single letter,
+which must be typed in lower case.
+Each command is typed
+on a separate line.
+(Sometimes the command is preceded by information
+about what line or lines of text are to be affected \-
+we will discuss these shortly.)
+.ul
+Ed
+makes no response
+to most commands \- there is no prompting
+or typing of messages like ``ready''.
+(This silence is preferred
+by experienced users, but sometimes a hangup for beginners.)
+.PP
+The first command is
+.UL append ,
+written as the letter
+.P1
+a
+.P2
+all
+by itself.
+It means ``append (or add) text lines to the buffer,
+as I type them in.''
+Appending is rather like
+writing fresh material on a piece of paper.
+.PP
+So to enter lines of text into the buffer,
+just type an
+.UL a
+followed by a
+.UC RETURN ,
+followed by the lines of text you want, like this:
+.P1
+a
+Now is the time
+for all good men
+to come to the aid of their party.
+\*.
+.P2
+.PP
+The only way to stop appending is to type a
+line that contains only a period.
+The ``\*.'' is used
+to tell
+.ul
+ed
+that you have finished appending.
+(Even experienced users forget that terminating ``\*.''
+sometimes.
+If
+.ul
+ed
+seems to be ignoring you,
+type an extra line with just ``\*.'' on it.
+You may then find you've added some garbage lines
+to your text, which you'll have to take out later.)
+.PP
+After the append command has been done, the buffer will
+contain the three lines
+.P1
+Now is the time
+for all good men
+to come to the aid of their party.
+.P2
+The
+.UL a '' ``
+and ``\*.'' aren't there, because they are
+not text.
+.PP
+To add more text to what you already have,
+just issue another
+.UL a
+command, and continue typing.
+.SH
+Error Messages \- ``?''
+.PP
+If at any time you make an error in the commands you type to
+.UL ed ,
+it will tell you by typing
+.P1
+?
+.P2
+This is about as cryptic as it can be,
+but with practice you can usually
+figure out how you goofed.
diff --git a/bin/ed/USD.doc/09.edtut/e2 b/bin/ed/USD.doc/09.edtut/e2
new file mode 100644
index 0000000..6f6668e
--- /dev/null
+++ b/bin/ed/USD.doc/09.edtut/e2
@@ -0,0 +1,463 @@
+.\" $OpenBSD: e2,v 1.5 2004/04/05 10:58:08 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)e2 8.1 (Berkeley) 6/8/93
+.\"
+.SH
+Writing text out as a file \- the Write command ``w''
+.PP
+It's likely that you'll want to save your text for later use.
+To write out the contents of the buffer onto a file,
+use the
+.ul
+write
+command
+.P1
+w
+.P2
+followed by the filename you want to write on.
+This will copy the buffer's contents
+onto the specified file
+(destroying any previous information on the file).
+To save
+the text on a file named
+.UL junk ,
+for example, type
+.P1
+w junk
+.P2
+Leave a space between
+.UL w
+and the file name.
+.ul
+Ed
+will respond by printing
+the number of characters it wrote out.
+In this case,
+.ul
+ed
+would respond with
+.P1
+68
+.P2
+(Remember that blanks and the return character at the end of each
+line are included in the character count.)
+Writing a file just makes a copy of the text \- the
+buffer's contents are not disturbed, so you can go on adding
+lines to it.
+This is an important point.
+.ul
+Ed
+at all times works on a copy
+of a file, not the file itself.
+No change in the contents
+of a file takes place until you give a
+.UL w
+command.
+(Writing out the text onto a file from time to time as it is being
+created is a good idea, since if the system crashes or if you make some horrible mistake, you will lose
+all the text in the buffer but any text that was written onto
+a file is relatively safe.)
+.SH
+Leaving ed \- the Quit command ``q''
+.PP
+To terminate a session with
+.IT ed ,
+save the text you're working on
+by writing it onto a file using the
+.UL w
+command,
+and then type the command
+.P1
+q
+.P2
+which
+stands for
+.IT quit .
+The system will respond with
+the prompt character
+.UL $ "" (
+or
+.UL % ).
+At
+this point your buffer vanishes, with all its text,
+which is why you want to write it out before quitting.**
+.FS
+** Actually,
+.IT ed
+will print
+.UL ?
+if you try to quit without writing.
+At that point, write if you want;
+if not, another
+.UL q
+will get you out regardless.
+.FE
+.SH
+Exercise 1:
+.PP
+Enter
+.ul
+ed
+and
+create some text using
+.P1
+a
+\&. . . text . . .
+\&\fB.\fR
+.P2
+Write it out using
+.UL w .
+Then leave
+.ul
+ed
+with the
+.UL q
+command, and print the file,
+to see that everything worked.
+(To print a file, say
+.P1
+pr filename
+.P2
+or
+.P1
+cat filename
+.P2
+in response to
+the prompt character.
+Try both.)
+.SH
+Reading text from a file \- the Edit command ``e''
+.PP
+A common way to get text into the buffer is to read it
+from a file in the file system.
+This is what you do to edit text
+that you saved with the
+.UL w
+command in a previous session.
+The
+.ul
+edit
+command
+.UL e
+fetches the entire contents of a file into the buffer.
+So if you had saved the three lines
+``Now is the time'', etc.,
+with a
+.UL w
+command in an earlier session,
+the
+.ul
+ed
+command
+.P1
+e junk
+.P2
+would fetch the entire contents of the file
+.UL junk
+into the buffer, and respond
+.P1
+68
+.P2
+which is the number of characters in
+.UL junk .
+.ul
+If anything was already in the buffer, it is deleted first.
+.PP
+If you use the
+.UL e
+command to read a file into the buffer,
+then you need not use a file name after a subsequent
+.UL w
+command;
+.ul
+ed
+remembers the last file name used in an
+.UL e
+command,
+and
+.UL w
+will write on this file.
+Thus a good way to operate is
+.P1
+ed
+e file
+[editing session]
+w
+q
+.P2
+This way, you can simply say
+.UL w
+from time to time,
+and be secure in the knowledge that
+if you got the file name right at the beginning,
+you are writing into the proper file each time.
+.PP
+You can find out at any time what file name
+.ul
+ed
+is remembering by typing the
+.ul
+file
+command
+.UL f .
+In this example,
+if you typed
+.P1
+f
+.P2
+.ul
+ed
+would reply
+.P1
+junk
+.P2
+.SH
+Reading text from a file \- the Read command ``r''
+.PP
+Sometimes you want to read a file into the buffer
+without destroying anything that is already there.
+This is done by the
+.ul
+read
+command
+.UL r .
+The command
+.P1
+r junk
+.P2
+will read the file
+.UL junk
+into the buffer;
+it adds it
+to the end of whatever is already in the buffer.
+So if you do a read after
+an edit:
+.P1
+e junk
+r junk
+.P2
+the buffer will contain
+.ul
+two
+copies of the text (six lines).
+.P1
+Now is the time
+for all good men
+to come to the aid of their party.
+Now is the time
+for all good men
+to come to the aid of their party.
+.P2
+Like the
+.UL w
+and
+.UL e
+commands,
+.UL r
+prints
+the
+number of characters read in, after the reading operation is complete.
+.PP
+Generally speaking,
+.UL r
+is much less used than
+.UL e .
+.SH
+Exercise 2:
+.PP
+Experiment with the
+.UL e
+command \-
+try reading and printing various files.
+You may get an error
+.UL "name: No such file or directory" ,
+where
+.UL name
+is the name of a file;
+this means that the file doesn't exist,
+typically because you spelled the file name wrongly,
+or perhaps that you are not allowed to read or write it.
+Try alternately reading and appending to see that they work
+similarly.
+Verify that
+.P1
+ed filename
+.P2
+is exactly equivalent to
+.P1
+ed
+e filename
+.P2
+What does
+.P1
+f filename
+.P2
+do?
+.SH
+Printing the contents of the buffer \- the Print command ``p''
+.PP
+To
+.ul
+print
+or list the contents of the buffer (or parts
+of it) on the terminal, use the print command
+.P1
+p
+.P2
+The way this is done is as follows:
+specify the lines where
+you want printing to begin and where you want it to end,
+separated by a comma, and
+followed by the letter
+.UL p .
+Thus to print the first two lines of the buffer, for
+example, (that is, lines 1 through 2) say
+.P1
+1,2p (starting line=1, ending line=2 p)
+.P2
+.ul
+Ed
+will respond with
+.P1
+Now is the time
+for all good men
+.P2
+.PP
+Suppose you want to print
+.ul
+all
+the lines in the buffer.
+You could use
+.UL 1,3p
+as above if you knew there were exactly
+3 lines in the buffer.
+But, in general, you don't
+know how many there are, so what do you use for the ending
+line number?
+.ul
+Ed
+provides a shorthand symbol for ``line number of
+last line in buffer'' \- the dollar sign
+.UL $ .
+Use it this
+way:
+.P1
+1,$p
+.P2
+This will print
+.ul
+all
+the lines in the buffer (line 1 to last line).
+If you want to stop the printing before it is finished,
+it can be interrupted with
+.UC ^C
+(Control-C);
+.ul
+ed
+will type
+.P1
+?
+.P2
+and wait for the next command.
+.PP
+To print the
+.ul
+last
+line of the buffer, you could use
+.P1
+$,$p
+.P2
+but
+.ul
+ed
+lets you abbreviate this to
+.P1
+$p
+.P2
+You can print any single line by typing the line
+number followed by a
+.UL p .
+Thus
+.P1
+1p
+.P2
+produces the response
+.P1
+Now is the time
+.P2
+which is the first line of the buffer.
+.PP
+In fact,
+.ul
+ed
+lets you abbreviate even further:
+you can print any single line by typing
+.ul
+just
+the line number \- no need to type the letter
+.UL p .
+So if you say
+.P1
+$
+.P2
+.ul
+ed
+will print the last line of the buffer.
+.PP
+You can also use
+.UL $
+in combinations like
+.P1
+$\-1,$p
+.P2
+which prints the last two lines of the buffer.
+This helps when you want to see how far you got in typing.
+.SH
+Exercise 3:
+.PP
+As before, create some text using the
+.UL a
+command and
+experiment with the
+.UL p
+command.
+You will find, for example,
+that you can't print line 0 or a line beyond
+the end of the buffer, and that attempts
+to print a buffer in reverse order by saying
+.P1
+3,1p
+.P2
+don't work.
diff --git a/bin/ed/USD.doc/09.edtut/e3 b/bin/ed/USD.doc/09.edtut/e3
new file mode 100644
index 0000000..90096f3
--- /dev/null
+++ b/bin/ed/USD.doc/09.edtut/e3
@@ -0,0 +1,417 @@
+.\" $OpenBSD: e3,v 1.4 2004/04/05 10:58:08 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)e3 8.1 (Berkeley) 6/8/93
+.\"
+.SH
+The current line \- ``Dot'' or ``.''
+.PP
+Suppose your buffer still contains the six lines as above,
+that you have just typed
+.P1
+1,3p
+.P2
+and
+.ul
+ed
+has printed the three lines for you.
+Try typing just
+.P1
+p (no line numbers)
+.P2
+This will print
+.P1
+to come to the aid of their party.
+.P2
+which is the third line of the buffer.
+In fact it is the last
+(most recent) line that you have done anything with.
+(You just printed it!)
+You can
+repeat this
+.UL p
+command without line numbers, and
+it will continue to print line 3.
+.PP
+The reason is that
+.ul
+ed
+maintains a record of the last line
+that you did anything to (in this case, line 3, which you
+just printed) so that it can be used instead of an explicit
+line number.
+This most recent line is referred to by the
+shorthand symbol
+.P1
+\&\*. (pronounced ``dot'')
+.P2
+Dot is a line number in the same way that
+.UL $
+is; it means
+exactly ``the current line'', or loosely,
+``the line you most recently did something to.''
+You
+can use it in several ways \- one possibility
+is to say
+.P1
+\&\*.,$p
+.P2
+This will print all the lines from (including) the current
+line to the
+end of the buffer.
+In our example these are lines 3 through 6.
+.PP
+Some commands change the value of dot, while others do not.
+The
+.UL p
+command sets dot to the number of the last line printed;
+the last command will
+set both
+\*.
+and
+.UL $
+to 6.
+.PP
+Dot is most useful when used in combinations like this one:
+.P1
+\&\*.+1 (or equivalently, \*.+1p)
+.P2
+This means ``print the next line'' and is a handy way to step
+slowly through a buffer.
+You can also say
+.P1
+\&\*.\-1 (or \*.\-1p)
+.P2
+which means ``print the line
+.ul
+before
+the current line.''
+This enables you to go backwards if you wish.
+Another useful one is something like
+.P1
+\&\*.\-3,\*.\-1p
+.P2
+which prints the previous three lines.
+.PP
+Don't forget that all of these change the value of dot.
+You can find out what dot is at any time by typing
+.P1
+\&\*.=
+.P2
+.ul
+Ed
+will respond by printing the value of dot.
+.PP
+Let's summarize some things about the
+.UL p
+command
+and dot.
+Essentially
+.UL p
+can be preceded by 0, 1, or 2 line numbers.
+If there is no line number given, it prints the ``current line'',
+the line that dot refers to.
+If there is one line number given
+(with or without the letter
+.UL p ),
+it prints that line (and dot is set there); and if there
+are two line numbers, it prints all the lines in that range
+(and sets dot to the last line printed).
+If two line numbers are specified
+the first can't be bigger than the second (see Exercise 2).
+.PP
+Typing a single return will cause printing of the next line \-
+it's
+equivalent to
+.UL .+1p .
+Try it.
+Try typing
+a
+.UL \- ;
+you will find that
+it's equivalent to
+.UL .\-1p .
+.SH
+Deleting lines: the ``d'' command
+.PP
+Suppose you want to get rid of the three extra lines in the buffer.
+This is done by the
+.ul
+delete
+command
+.P1
+d
+.P2
+Except that
+.UL d
+deletes lines instead of printing them,
+its action is similar to that of
+.UL p .
+The lines to be deleted are specified for
+.UL d
+exactly as they are for
+.UL p :
+.P1
+\fIstarting line, ending line\fP d
+.P2
+Thus the command
+.P1
+4,$d
+.P2
+deletes lines 4 through the end.
+There are now three lines left, as you can check by using
+.P1
+1,$p
+.P2
+And notice that
+.UL $
+now is line 3!
+Dot
+is set to the next line after the last line deleted,
+unless the last line deleted is the last line in the buffer.
+In that case, dot is set to
+.UL $ .
+.SH
+Exercise 4:
+.PP
+Experiment with
+.UL a ,
+.UL e ,
+.UL r ,
+.UL w ,
+.UL p ,
+and
+.UL d
+until you are sure that you
+know what they do, and until you understand how dot,
+.UL $ ,
+and
+line numbers are used.
+.PP
+If you are adventurous, try using line numbers with
+.UL a ,
+.UL r ,
+and
+.UL w
+as well.
+You will find that
+.UL a
+will append lines
+.ul
+after
+the line number that you specify (rather than after dot); that
+.UL r
+reads
+a file in
+.ul
+after
+the line number you specify (not necessarily
+at the end of the buffer); and that
+.UL w
+will write out exactly the lines
+you specify, not necessarily the whole buffer.
+These variations are sometimes handy.
+For instance you can insert a file at the beginning of a buffer
+by saying
+.P1
+0r filename
+.P2
+and you can enter lines at the beginning of the buffer
+by saying
+.P1
+0a
+\&. . . \fItext\fP . . .
+\*.
+.P2
+Notice that
+.UL .w
+is
+.ul
+very
+different from
+.P1
+\*.
+w
+.P2
+.SH
+Modifying text: the Substitute command ``s''
+.PP
+We are now ready to try one of the most important
+of all commands \- the substitute command
+.P1
+s
+.P2
+This is the command
+that is used to change individual
+words or letters within a line or group of lines.
+It is what you use, for example, for correcting spelling
+mistakes and typing errors.
+.PP
+Suppose that by a typing error, line 1 says
+.P1
+Now is th time
+.P2
+\- the
+.IT e
+has been left off
+.IT the .
+You can use
+.UL s
+to fix this up as follows:
+.P1
+1s/th/the/
+.P2
+This says: ``in line 1, substitute for the characters
+.IT th
+the characters
+.IT the .''
+To verify
+that it works
+.IT ed "" (
+will not print
+the result automatically) say
+.P1
+p
+.P2
+and get
+.P1
+Now is the time
+.P2
+which is what you wanted.
+Notice that dot must have been set to the line
+where the substitution took place, since the
+.UL p
+command
+printed that line.
+Dot is always set this way with the
+.UL s
+command.
+.PP
+The general way to use the substitute command is
+.P1
+\fIstarting\(hyline, ending\(hyline\fP s/\fIchange this\fP/\fIto this\fP/
+.P2
+Whatever string of characters is between the first pair of
+slashes is replaced by whatever is between the second pair,
+in
+.ul
+all
+the lines between
+.UL starting-line
+and
+.UL ending-line .
+Only the first occurrence on each line is changed, however.
+If you want to change
+.ul
+every
+occurrence, see Exercise 5.
+The rules for line numbers are the same as those for
+.UL p ,
+except that dot is set to the last line changed.
+(But there is a trap for the unwary: if no substitution
+took place, dot is
+.ul
+not
+changed.
+This causes an error
+.UL ?
+as a warning.)
+.PP
+Thus you can say
+.P1
+1,$s/speling/spelling/
+.P2
+and correct the first spelling mistake
+on each line
+in the text.
+(This is useful for people who are consistent
+misspellers!)
+.PP
+If no line numbers are given, the
+.UL s
+command assumes we mean
+``make the substitution on line dot'', so it changes things only
+on the current line.
+This leads to the very common sequence
+.P1
+s/something/something else/p
+.P2
+which makes some correction on the
+current line, and then prints it, to make sure it
+worked out right.
+If it didn't,
+you can try again.
+(Notice that there is
+a
+.UL p
+on the same line as the
+.UL s
+command.
+With few exceptions,
+.UL p
+can follow any command;
+no other multi-command lines are legal.)
+.PP
+It's also legal to say
+.P1
+s/ . . . //
+.P2
+which means ``change the first
+string of characters to
+.IT nothing '', ``
+i.e.,
+remove them.
+This is useful for deleting extra words in a line or removing extra
+letters from words.
+For instance, if you had
+.P1
+Nowxx is the time
+.P2
+you can say
+.P1
+s/xx//p
+.P2
+to get
+.P1
+Now is the time
+.P2
+Notice that
+.UL //
+(two adjacent slashes) means ``no characters'', not a blank.
+There
+.ul
+is
+a difference!
+(See below for another meaning of
+.UL // .)
diff --git a/bin/ed/USD.doc/09.edtut/e4 b/bin/ed/USD.doc/09.edtut/e4
new file mode 100644
index 0000000..582cf57
--- /dev/null
+++ b/bin/ed/USD.doc/09.edtut/e4
@@ -0,0 +1,303 @@
+.\" $OpenBSD: e4,v 1.3 2004/04/05 10:58:08 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)e4 8.1 (Berkeley) 6/8/93
+.\"
+.SH
+Exercise 5:
+.PP
+Experiment with the substitute command.
+See what happens if you
+substitute for some word on a line with several occurrences of that word.
+For example, do this:
+.P1
+a
+the other side of the coin
+\*.
+s/the/on the/p
+.P2
+You will get
+.P1
+on the other side of the coin
+.P2
+A substitute command changes only the first occurrence of the first string.
+You can change all occurrences by adding a
+.UL g
+(for ``global'')
+to the
+.UL s
+command, like this:
+.P1
+s/ . . . / . . . /gp
+.P2
+Try other characters instead of slashes to delimit the two sets
+of characters in the
+.UL s
+command \- anything should work
+except blanks or tabs.
+.PP
+(If you get funny results using any of the characters
+.P1
+^ \*. $ [ * \e &
+.P2
+read the section on ``Special Characters''.)
+.SH
+Context searching \- ``/ . . . /''
+.PP
+With the substitute command mastered, you can move on to
+another highly important idea of
+.ul
+ed
+\- context searching.
+.PP
+Suppose you have the original three line text in the buffer:
+.P1
+Now is the time
+for all good men
+to come to the aid of their party.
+.P2
+Suppose you want to find the line that contains
+.IT their
+so
+you can change it to
+.IT the .
+Now with only three lines in the buffer, it's pretty easy
+to keep track of what line the word
+.IT their
+is on.
+But if the buffer contained several hundred lines,
+and you'd been making changes, deleting and rearranging lines,
+and so on, you would no longer really know what this line
+number would be.
+Context searching is simply a method of specifying the desired line,
+regardless of what its number is,
+by specifying some context on it.
+.PP
+The way to say ``search for a line
+that contains this particular string of characters''
+is to type
+.P1
+/\fIstring of characters we want to find\fP/
+.P2
+For example,
+the
+.ul
+ed
+command
+.P1
+/their/
+.P2
+is a context search which
+is sufficient to find the desired line \-
+it will locate the next occurrence of
+the characters between slashes (``their'').
+It also sets dot to that line
+and prints the line for verification:
+.P1
+to come to the aid of their party.
+.P2
+``Next occurrence'' means that
+.ul
+ed
+starts looking for the string at line
+.UL .+1 ,
+searches to the end of the buffer,
+then continues at line 1 and searches to line dot.
+(That is, the search ``wraps around'' from
+.UL $
+to
+1.)
+It scans all the lines in the buffer until it either finds the desired line
+or gets back to dot again.
+If the given string of characters can't be found in any line,
+.ul
+ed
+types the error message
+.P1
+?
+.P2
+Otherwise it prints the line it found.
+.PP
+You can do both the search for the desired line
+.ul
+and
+a
+substitution all at once, like this:
+.P1
+/their/s/their/the/p
+.P2
+which will yield
+.P1
+to come to the aid of the party.
+.P2
+There were three parts to that last command:
+context search for the desired line, make the substitution, print the line.
+.PP
+The expression
+.UL /their/
+is a context search expression.
+In their simplest form,
+all context search expressions are like this \-
+a string of characters surrounded by slashes.
+Context searches are interchangeable with line numbers,
+so they can be used by themselves to find and print a desired line,
+or as line numbers for some other command, like
+.UL s .
+They were used both ways in the examples above.
+.PP
+Suppose the buffer contains the three familiar lines
+.P1
+Now is the time
+for all good men
+to come to the aid of their party.
+.P2
+Then the
+.ul
+ed
+line numbers
+.P1
+/Now/+1
+/good/
+/party/\-1
+.P2
+are all context search expressions, and they all refer
+to the same line (line 2).
+To make a change in line 2,
+you could say
+.P1
+/Now/+1s/good/bad/
+.P2
+or
+.P1
+/good/s/good/bad/
+.P2
+or
+.P1
+/party/\-1s/good/bad/
+.P2
+The choice is dictated only by convenience.
+You could print all three lines by, for instance
+.P1
+/Now/,/party/p
+.P2
+or
+.P1
+/Now/,/Now/+2p
+.P2
+or by any number of similar combinations.
+The first one of these might be better if you don't
+know how many lines are involved.
+(Of course, if there were only three lines in the buffer,
+you'd use
+.P1
+1,$p
+.P2
+but not if there were several hundred.)
+.PP
+The basic rule is: a context search expression is
+.ul
+the same as
+a line number, so it can be used wherever a line number is needed.
+.SH
+Exercise 6:
+.PP
+Experiment with context searching.
+Try a body of text with
+several occurrences
+of the same string of characters, and scan through it using
+the same context search.
+.PP
+Try using context searches as line numbers for the
+substitute, print, and delete commands.
+(They can also be used
+with
+.UL r ,
+.UL w ,
+and
+.UL a .)
+.PP
+Try context searching using
+.UL ?text?
+instead of
+.UL /text/ .
+This scans lines in the buffer in reverse order
+rather than normal.
+This is
+sometimes useful if you go too far while looking for some
+string of characters \- it's an easy way to back up.
+.PP
+(If you get funny results with any of the characters
+.P1
+^ \*. $ [ * \e &
+.P2
+read the section on ``Special Characters''.)
+.PP
+.ul
+Ed
+provides a shorthand for repeating a context search
+for the same string.
+For example,
+the
+.ul
+ed
+line number
+.P1
+/string/
+.P2
+will find the next occurrence of
+.UL string .
+It often happens that this is not the desired line,
+so the search must be repeated.
+This can be done by typing merely
+.P1
+//
+.P2
+This shorthand stands for ``the most recently used
+context search expression.''
+It can
+also be used as the first string of the substitute
+command, as in
+.P1
+/string1/s//string2/
+.P2
+which will find the next occurrence of
+.UL string1
+and replace it by
+.UL string2 .
+This can save a lot of typing.
+Similarly
+.P1
+??
+.P2
+means ``scan backwards for the same expression.''
diff --git a/bin/ed/USD.doc/09.edtut/e5 b/bin/ed/USD.doc/09.edtut/e5
new file mode 100644
index 0000000..e44c523
--- /dev/null
+++ b/bin/ed/USD.doc/09.edtut/e5
@@ -0,0 +1,310 @@
+.\" $OpenBSD: e5,v 1.2 2003/06/26 16:24:16 mickey Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)e5 8.1 (Berkeley) 6/8/93
+.\"
+.SH
+Change and Insert \- ``c'' and ``i''
+.PP
+This section discusses the
+.ul
+change
+command
+.P1
+c
+.P2
+which is used to change
+or replace a group of one or more lines,
+and the
+.ul
+insert
+command
+.P1
+i
+.P2
+which is used for inserting a group of one or more lines.
+.PP
+``Change'', written as
+.P1
+c
+.P2
+is used to replace a number of lines with different lines, which
+are typed in at the terminal.
+For example,
+to change lines
+.UL .+1
+through
+.UL $
+to something else, type
+.P1
+\&.+1,$c
+\&. . . \fItype the lines of text you want here\fP . . .
+\*.
+.P2
+The lines you type between the
+.UL c
+command and
+the
+.UL .
+will take the place of the original lines between
+start line and end line.
+This is most useful in replacing a line
+or several lines which have errors in them.
+.PP
+If only one line is specified in the
+.UL c
+command, then just
+that line is replaced.
+(You can type in as many replacement lines as you like.)
+Notice
+the use of
+.UL .
+to end the
+input \- this works just like the
+.UL .
+in the append command
+and must appear by itself on a new line.
+If no line number is given, line dot is replaced.
+The value of dot is set to the last line you typed in.
+.PP
+``Insert'' is similar to append \- for instance
+.P1
+/string/i
+\&. . . \fItype the lines to be inserted here\fP . . .
+\*.
+.P2
+will insert the given text
+.ul
+before
+the next line that contains ``string''.
+The text between
+.UL i
+and
+.UL .
+is
+.ul
+inserted before
+the specified line.
+If no line number is specified dot is used.
+Dot is set to the last line inserted.
+.SH
+Exercise 7:
+.PP
+``Change'' is rather like a combination of
+delete followed by insert.
+Experiment to verify that
+.P1
+\fIstart, end\fP d
+i
+.ul
+\&. . . text . . .
+\*.
+.P2
+is almost the same as
+.P1
+\fIstart, end\fP c
+.ul
+\&. . . text . . .
+\*.
+.P2
+These are not
+.ul
+precisely
+the same
+if line
+.UL $
+gets deleted.
+Check this out.
+What is dot?
+.PP
+Experiment with
+.UL a
+and
+.UL i ,
+to see that they are
+similar, but not the same.
+You will observe that
+.P1
+\fIline\(hynumber\fP a
+\&. . . \fItext\fP . . .
+\*.
+.P2
+appends
+.ul
+after
+the given line, while
+.P1
+\fIline\(hynumber\fP i
+\&. . . \fItext\fP . . .
+\*.
+.P2
+inserts
+.ul
+before
+it.
+Observe that if no line number is given,
+.UL i
+inserts before line dot, while
+.UL a
+appends
+after line dot.
+.SH
+Moving text around: the ``m'' command
+.PP
+The move command
+.UL m
+is used for cutting and pasting \-
+it lets you move a group of lines
+from one place to another in the buffer.
+Suppose you want to put the first three lines of the buffer at the end instead.
+You could do it by saying:
+.P1
+1,3w temp
+$r temp
+1,3d
+.P2
+(Do you see why?)
+but you can do it a lot easier with the
+.UL m
+command:
+.P1
+1,3m$
+.P2
+The general case is
+.P1
+\fIstart line, end line\fP m \fIafter this line\fP
+.P2
+Notice that there is a third line to be specified \-
+the place where the moved stuff gets put.
+Of course the lines to be moved can be specified
+by context searches;
+if you had
+.P1
+First paragraph
+\&. . .
+end of first paragraph.
+Second paragraph
+\&. . .
+end of second paragraph.
+.P2
+you could reverse the two paragraphs like this:
+.P1
+/Second/,/end of second/m/First/\-1
+.P2
+Notice the
+.UL \-1 :
+the moved text goes
+.ul
+after
+the line mentioned.
+Dot gets set to the last line moved.
+.SH
+The global commands ``g'' and ``v''
+.PP
+The
+.ul
+global
+command
+.UL g
+is used to execute one or more
+.ul
+ed
+commands on all those lines in the buffer
+that match some specified string.
+For example
+.P1
+g/peling/p
+.P2
+prints all lines that contain
+.UL peling .
+More usefully,
+.P1
+g/peling/s//pelling/gp
+.P2
+makes the substitution everywhere on the line,
+then prints each corrected line.
+Compare this to
+.P1
+1,$s/peling/pelling/gp
+.P2
+which only prints the last line substituted.
+Another subtle difference is that
+the
+.UL g
+command
+does not give a
+.UL ?
+if
+.UL peling
+is not found
+where the
+.UL s
+command will.
+.PP
+There may be several commands
+(including
+.UL a ,
+.UL c ,
+.UL i ,
+.UL r ,
+.UL w ,
+but not
+.UL g );
+in that case,
+every line except the last must end with a backslash
+.UL \e :
+.P1
+g/xxx/\*.-1s/abc/def/\e
+\&\*.+2s/ghi/jkl/\e
+\&\*.-2,\*.p
+.P2
+makes changes in the lines before and after each line
+that contains
+.UL xxx ,
+then prints all three lines.
+.PP
+The
+.UL v
+command is the same as
+.UL g ,
+except that the commands are executed on every line
+that does
+.ul
+not
+match the string following
+.UL v :
+.P1
+v/ /d
+.P2
+deletes every line that does not contain a blank.
diff --git a/bin/ed/USD.doc/09.edtut/e6 b/bin/ed/USD.doc/09.edtut/e6
new file mode 100644
index 0000000..cb54653
--- /dev/null
+++ b/bin/ed/USD.doc/09.edtut/e6
@@ -0,0 +1,277 @@
+.\" $OpenBSD: e6,v 1.3 2004/04/05 10:58:08 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)e6 8.1 (Berkeley) 6/8/93
+.\"
+.SH
+Special Characters
+.PP
+You may have noticed that things just don't work right when you used
+some characters like
+\*.,
+.UL * ,
+.UL $ ,
+and others in
+context searches and the substitute command.
+The reason is rather complex, although the cure is simple.
+Basically,
+.ul
+ed
+treats these characters as special, with special meanings.
+For instance,
+.ul
+in a context search or the first string of the substitute command only,
+\*.
+means ``any character,'' not a period, so
+.P1
+/x\*.y/
+.P2
+means ``a line with an
+.UL x ,
+.UL "any character" ,
+and a
+.UL y ,''
+.ul
+not
+just ``a line with an
+.UL x ,
+a period, and a
+.UL y .''
+A complete list of the special characters
+that can cause trouble is the following:
+.P1
+^ \*. $ [ * \e &
+.P2
+.ul
+Warning:
+The backslash character
+.UL \e
+is special to
+.UL ed .
+For safety's sake,
+avoid it where possible.
+If you have to use one of the special characters
+in a substitute command,
+you can turn off its magic meaning temporarily
+by preceding it with the backslash.
+Thus
+.P1
+s/\e\e\e\*.\e*/backslash dot star/
+.P2
+will change
+.UL \e.*
+into ``backslash dot star''.
+.PP
+Here is a hurried synopsis of the other special characters.
+First, the circumflex
+.UL ^
+signifies
+the beginning of a line.
+Thus
+.P1
+/^string/
+.P2
+finds
+.UL string
+only if it is at the beginning of a line:
+it will find
+.P1
+string
+.P2
+but not
+.P1
+the string...
+.P2
+The dollar-sign
+.UL $
+is just the opposite of the circumflex;
+it means the end of a line:
+.P1
+/string$/
+.P2
+will only find an occurrence of
+.UL string
+that is at the end of some line.
+This implies, of course,
+that
+.P1
+/^string$/
+.P2
+will find only a line that contains just
+.UL string ,
+and
+.P1
+/^\*.$/
+.P2
+finds a line containing exactly one character.
+.PP
+The character
+.UL . ,
+as we mentioned above,
+matches anything;
+.P1
+/x\*.y/
+.P2
+matches any of
+.P1
+x+y
+x-y
+x y
+x\*.y
+.P2
+This is useful in conjunction with
+.UL * ,
+which is a repetition character;
+.UL a*
+is a shorthand for ``any number of
+.UL a 's,''
+so
+.UL .*
+matches any number of anythings.
+This is used like this:
+.P1
+s/\*.*/stuff/
+.P2
+which changes an entire line,
+or
+.P1
+s/\*.*,//
+.P2
+which deletes all characters in the line up to and
+including the last comma.
+(Since
+.UL .*
+finds the longest possible match,
+this goes up to the last comma.)
+.PP
+.UL [
+is used with
+.UL ]
+to form ``character classes'';
+for example,
+.P1
+/[0123456789]/
+.P2
+matches any single digit \-
+any one of the characters inside the braces
+will cause a match.
+This can be abbreviated to
+.UL [0\-9] .
+.PP
+Finally, the
+.UL &
+is another shorthand character \-
+it is used only on the right-hand part of a substitute command
+where it means ``whatever was matched on the left-hand side''.
+It is used to save typing.
+Suppose the current line contained
+.P1
+Now is the time
+.P2
+and you wanted to put parentheses around it.
+You could just retype the line, but
+this is tedious.
+Or you could say
+.P1
+s/^/(/
+s/$/)/
+.P2
+using your knowledge of
+.UL ^
+and
+.UL $ .
+But the easiest way uses the
+.UL & :
+.P1
+s/\*.*/(&)/
+.P2
+This says ``match the whole line, and replace it
+by itself surrounded by parentheses.''
+The
+.UL &
+can be used several times in a line;
+consider
+using
+.P1
+s/\*.*/&? &!!/
+.P2
+to produce
+.P1
+Now is the time? Now is the time!!
+.P2
+.PP
+You don't have to match the whole line, of course:
+if the buffer contains
+.P1
+the end of the world
+.P2
+you could type
+.P1
+/world/s//& is at hand/
+.P2
+to produce
+.P1
+the end of the world is at hand
+.P2
+Observe this expression carefully,
+for it illustrates how to take advantage of
+.ul
+ed
+to save typing.
+The string
+.UL /world/
+found the desired line;
+the shorthand
+.UL //
+found the same
+word in the line;
+and the
+.UL &
+saves you from typing it again.
+.PP
+The
+.UL &
+is a special character only within
+the replacement text of a substitute command,
+and has no special meaning elsewhere.
+You can turn off the special meaning of
+.UL &
+by preceding it with a
+.UL \e :
+.P1
+s/ampersand/\e&/
+.P2
+will convert the word ``ampersand'' into the literal symbol
+.UL &
+in the current line.
diff --git a/bin/ed/USD.doc/09.edtut/e7 b/bin/ed/USD.doc/09.edtut/e7
new file mode 100644
index 0000000..0120f58
--- /dev/null
+++ b/bin/ed/USD.doc/09.edtut/e7
@@ -0,0 +1,227 @@
+.\" $OpenBSD: e7,v 1.4 2004/04/05 10:58:08 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)e7 8.1 (Berkeley) 6/8/93
+.\"
+.sp 2
+.SH
+Summary of Commands and Line Numbers
+.PP
+The general form of
+.ul
+ed
+commands is the command name,
+perhaps preceded by one or two line numbers, and,
+in the case of
+.UL e ,
+.UL r ,
+and
+.UL w ,
+followed by a file name.
+Only one command is allowed per line,
+but a
+.UL p
+command may follow any other command
+(except for
+.UL e ,
+.UL r ,
+.UL w ,
+and
+.UL q ).
+.LP
+.UL a :
+Append, that is,
+add lines to the buffer (at line dot, unless
+a different line is specified). Appending continues until
+\*.
+is typed on a new line.
+Dot is set to the last line appended.
+.LP
+.UL c :
+Change the specified lines to the new text which follows.
+The new lines are terminated by a
+\*.,
+as with
+.UL a .
+If no lines are specified,
+replace line dot.
+Dot is set to the last line changed.
+.LP
+.UL d :
+Delete the lines specified.
+If none are specified, delete line dot.
+Dot is set to the first undeleted line,
+unless
+.UL $
+is deleted,
+in which case dot is set to
+.UL $ .
+.LP
+.UL e :
+Edit new file.
+Any previous
+contents of the buffer are thrown away,
+so issue a
+.UL w
+beforehand.
+.LP
+.UL f :
+Print remembered filename.
+If a name follows
+.UL f
+the remembered name will be set to it.
+.LP
+.UL g :
+The command
+.P1
+g/\(hy\(hy\(hy/commands
+.P2
+will execute the commands on those lines that contain
+.UL --- ,
+which can be any context search expression.
+.LP
+.UL i :
+Insert lines before specified line (or dot)
+until a
+\*.
+is typed on a new line.
+Dot is set to last line inserted.
+.LP
+.UL m :
+Move lines specified to after the line
+named after
+.UL m .
+Dot is set to the last line moved.
+.LP
+.UL p :
+Print specified lines.
+If none specified, print
+line dot.
+A single line number is equivalent to
+.IT line-number
+.UL p .
+A single return prints
+.UL .+1 ,
+the next line.
+.LP
+.UL q :
+Quit
+.IT ed .
+Wipes out all text in buffer
+if you give it twice in a row without first giving a
+.UL w
+command.
+.LP
+.UL r :
+Read a file into buffer (at end unless specified
+elsewhere.) Dot set to last line read.
+.LP
+.UL s :
+The command
+.P1
+s/string1/string2/
+.P2
+substitutes the characters
+.UL string1
+into
+.UL string2
+in the specified lines.
+If no lines are specified, make the substitution in line dot.
+Dot is set to the last line in which a
+substitution took place, which means that if no substitution took place, dot is not changed.
+.UL s
+changes only the first occurrence of
+.UL string1
+on a line;
+to change all of them, type a
+.UL g
+after the final slash.
+.LP
+.UL v :
+The command
+.P1
+v/\(hy\(hy\(hy/commands
+.P2
+executes
+.UL commands
+on those lines that
+.ul
+do not
+contain
+.UL --- .
+.LP
+.UL w :
+Write out buffer onto a file.
+Dot is not changed.
+.LP
+.UL .= :
+Print value of dot.
+.UL = "" (
+by itself prints the value of
+.UL $ .)
+.LP
+.UL ! :
+The line
+.P1
+!command\(hyline
+.P2
+causes
+.UL command-line
+to be executed as a
+.UC UNIX
+command.
+.LP
+.UL /-----/ :
+Context search.
+Search for next line which contains
+this string of characters.
+Print it.
+Dot is set to the line where string
+was found.
+Search starts at
+.UL .+1 ,
+wraps around from
+.UL $
+to
+1,
+and continues to dot, if necessary.
+.LP
+.UL ?-----? :
+Context search in reverse direction.
+Start search
+at
+.UL .\-1 ,
+scan to 1,
+wrap around to
+.UL $ .
diff --git a/bin/ed/USD.doc/10.edadv/Makefile b/bin/ed/USD.doc/10.edadv/Makefile
new file mode 100644
index 0000000..be22f0a
--- /dev/null
+++ b/bin/ed/USD.doc/10.edadv/Makefile
@@ -0,0 +1,10 @@
+# $OpenBSD: Makefile,v 1.2 2004/02/01 15:21:55 jmc Exp $
+
+DIR= usd/10.edadv
+SRCS= ae.mac ae0 ae1 ae2 ae3 ae4 ae5 ae6 ae7 ae9
+MACROS= -ms
+
+paper.txt: ${SRCS}
+ ${ROFF} -Tascii ${SRCS} > ${.TARGET}
+
+include bsd.doc.mk
diff --git a/bin/ed/USD.doc/10.edadv/ae.mac b/bin/ed/USD.doc/10.edadv/ae.mac
new file mode 100644
index 0000000..8c0f451
--- /dev/null
+++ b/bin/ed/USD.doc/10.edadv/ae.mac
@@ -0,0 +1,86 @@
+.\" $OpenBSD: ae.mac,v 1.3 2004/04/05 16:27:21 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)ae.mac 8.1 (Berkeley) 8/14/93
+.\"
+.tr _\(em
+.de UL
+\&\\$3\f2\\$1\f1\\$2
+..
+.de IT
+\&\\$3\f2\\$1\fP\\$2
+..
+.de UI
+\f3\\$1\fI\\$2\fR\\$3
+..
+.de P1
+.if n .ls 1
+.nf
+.if n .ta 5 10 15 20 25 30 35 40 45 50 55 60
+.if t .ta .3i .6i .9i 1.2i 1.5i 1.8i
+.tr -\-
+.\" use first argument as indent if present
+.if \\n(.$ .DS I \\$1
+.if !\\n(.$ .DS I 5
+.bd 1 2
+..
+.de P2
+.br
+.bd 1 2
+.DE
+.bd 1
+.tr --
+.if n .ls 1
+..
+.if t .ds BL \s6\|\v'.1m'\(sq\v'-.1m'\|\s0
+.if n .ds BL []
+.if t .ds m \(mi
+.if n .ds m -
+.if t .ds n \(no
+.if n .ds n -
+.if t .ds s \v'.41m'\s+4*\s-4\v'-.41m'
+.if n .ds s *
+.if t .ds S \(sl
+.if n .ds S /
+.if t .ds d \s+4\&.\&\s-4
+.if n .ds d \&.\&
+.if t .ds a \z@@
+.if n .ds a @
+.if t .ds . \s+2\fB.\fP\s-2
+.if n .ds . .
+.if t .ds e \z\e\h'1u'\e
+.if n .ds e \e
+.hy 14
+.\" 2=not last lines; 4= no -xx; 8=no xx-
+.tr *\(**
diff --git a/bin/ed/USD.doc/10.edadv/ae0 b/bin/ed/USD.doc/10.edadv/ae0
new file mode 100644
index 0000000..a59de56
--- /dev/null
+++ b/bin/ed/USD.doc/10.edadv/ae0
@@ -0,0 +1,102 @@
+.\" $OpenBSD: ae0,v 1.4 2004/04/06 08:19:20 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)ae0 8.1 (Berkeley) 8/14/93
+.\"
+.if n \{\
+.po 5n
+.ll 70n
+.\}
+.nr P1 1
+.EH 'USD:10-%''Advanced Editing on \s-2UNIX\s+2'
+.OH 'Advanced Editing on \s-2UNIX\s+2''USD:10-%'
+.\" .....TM 76-1273-8 39199 39199-11
+.\".RP
+.TL
+Advanced Editing on \s-2UNIX\s+2
+.AU "MH 2C518" 6021
+Brian W. Kernighan
+.AI
+Murray Hill, NJ
+.AU
+(Updated for 4.3BSD by Mark Seiden)
+.AB
+This paper is meant to help
+secretaries, typists and programmers
+to make effective use of the
+.UX
+facilities
+for preparing and editing text.
+It provides explanations and examples of
+.IP \(bu
+special characters, line addressing, and global commands in the editor
+.UL ed ;
+.IP \(bu
+commands for ``cut and paste'' operations on files
+and parts of files,
+including the
+.UL mv ,
+.UL cp ,
+.UL cat ,
+and
+.UL rm
+commands,
+and the
+.UL r ,
+.UL w ,
+.UL m ,
+and
+.UL t
+commands of the editor;
+.IP \(bu
+editing scripts and
+editor-based programs like
+.UL grep
+and
+.UL sed .
+.PP
+Although the treatment is aimed
+at non-programmers,
+new
+UNIX
+users
+with any background
+should find helpful hints
+on how to get their jobs done
+more easily.
+.AE
+.\" .CS 16 0 16 0 0 3
+.\" .if n .ls 2
+.nr PS 9
+.nr VS 11
diff --git a/bin/ed/USD.doc/10.edadv/ae1 b/bin/ed/USD.doc/10.edadv/ae1
new file mode 100644
index 0000000..e1818b6
--- /dev/null
+++ b/bin/ed/USD.doc/10.edadv/ae1
@@ -0,0 +1,104 @@
+.\" $OpenBSD: ae1,v 1.3 2004/04/06 08:19:20 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)ae1 8.1 (Berkeley) 6/8/93
+.\"
+.NH
+INTRODUCTION
+.PP
+Although
+.UX
+provides remarkably effective tools for text editing,
+that by itself is no guarantee
+that everyone will automatically
+make the most effective use of them.
+In particular, people who are not computer specialists _
+typists, secretaries, casual users _
+often use the system less effectively than they might.
+(There is a good argument that new users would better use their time
+learning a display editor, like
+.UL vi ,
+or perhaps a version of
+.UL emacs ,
+like
+.UL jove ,
+rather than an editor as ignorant of display terminals as
+.UL ed .)
+.PP
+This document is intended as a sequel to
+.ul
+A Tutorial Introduction to the UNIX Text Editor
+[1],
+providing explanations and examples of how to edit using
+.ul
+ed
+with less effort.
+(You should also be familiar with the material in
+.ul
+UNIX For Beginners
+[2].)
+Further information on all commands discussed here can be found in
+section 1 of the
+.ul
+The UNIX User's Manual
+[3].
+.PP
+Examples are based on observations
+of users
+and the difficulties they encounter.
+Topics covered include special characters in searches and substitute commands,
+line addressing, the global commands,
+and line moving and copying.
+There are also brief discussions of
+effective use
+of related tools, like those for file manipulation,
+and those based on
+.UL ed ,
+like
+.UL grep
+and
+.UL sed .
+.PP
+A word of caution.
+There is only one way to learn to use something,
+and that is to
+.ul
+use
+it.
+Reading a description is no substitute
+for trying something.
+A paper like this one should
+give you ideas about what to try,
+but until you actually try something,
+you will not learn it.
diff --git a/bin/ed/USD.doc/10.edadv/ae2 b/bin/ed/USD.doc/10.edadv/ae2
new file mode 100644
index 0000000..b0e8a07
--- /dev/null
+++ b/bin/ed/USD.doc/10.edadv/ae2
@@ -0,0 +1,1015 @@
+.\" $OpenBSD: ae2,v 1.4 2004/04/06 08:19:20 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)ae2 8.1 (Berkeley) 6/8/93
+.\"
+.NH
+SPECIAL CHARACTERS
+.PP
+The editor
+.UL ed
+is the primary interface to the system
+for many people, so
+it is worthwhile to know
+how to get the most out of
+.UL ed
+for the least effort.
+.PP
+The next few sections will discuss
+shortcuts
+and labor-saving devices.
+Not all of these will be instantly useful
+to any one person, of course,
+but a few will be,
+and the others should give you ideas to store
+away for future use.
+And as always,
+until you try these things,
+they will remain theoretical knowledge,
+not something you have confidence in.
+.SH
+The List command `l'
+.PP
+.UL ed
+provides two commands for printing the contents of the lines
+you're editing.
+Most people are familiar with
+.UL p ,
+in combinations like
+.P1
+1,$p
+.P2
+to print all the lines you're editing,
+or
+.P1
+s/abc/def/p
+.P2
+to change
+`abc'
+to
+`def'
+on the current line.
+Less familiar is the
+.ul
+list
+command
+.UL l
+(the letter `\fIl\|\fR'),
+which gives slightly more information than
+.UL p .
+In particular,
+.UL l
+makes visible characters that are normally invisible,
+such as tabs.
+If you list a line that contains tabs,
+.UL l
+will print each tab as
+.UL \*et .
+This makes it much easier to correct the sort of typing mistake
+that inserts extra spaces adjacent to tabs,
+or inserts a backspace followed by a space.
+.PP
+The
+.UL l
+command
+also `folds' long lines for printing _
+any line that exceeds 72 characters is printed on multiple lines;
+each printed line except the last is terminated by a backslash
+.UL \*e ,
+so you can tell it was folded.
+This is useful for printing long lines on short terminals.
+.PP
+Occasionally the
+.UL l
+command will print in a line a string of numbers preceded by a backslash,
+such as \*e07 or \*e16.
+These combinations are used to make visible characters that normally don't print,
+like form feed or vertical tab or bell.
+Each such combination is a single character.
+When you see such characters, be wary _
+they may have surprising meanings when printed on some terminals.
+Often their presence means that your finger slipped while you were typing;
+you almost never want them.
+.SH
+The Substitute Command `s'
+.PP
+Most of the next few sections will be taken up with a discussion
+of the
+substitute
+command
+.UL s .
+Since this is the command for changing the contents of individual
+lines,
+it probably has the most complexity of any
+.UL ed
+command,
+and the most potential for effective use.
+.PP
+As the simplest place to begin,
+recall the meaning of a trailing
+.UL g
+after a substitute command.
+With
+.P1
+s/this/that/
+.P2
+and
+.P1
+s/this/that/g
+.P2
+the
+first
+one replaces the
+.ul
+first
+`this' on the line
+with `that'.
+If there is more than one `this' on the line,
+the second form
+with the trailing
+.UL g
+changes
+.ul
+all
+of them.
+.PP
+Either form of the
+.UL s
+command can be followed by
+.UL p
+or
+.UL l
+to `print' or `list' (as described in the previous section)
+the contents of the line:
+.P1
+s/this/that/p
+s/this/that/l
+s/this/that/gp
+s/this/that/gl
+.P2
+are all legal, and mean slightly different things.
+Make sure you know what the differences are.
+.PP
+Of course, any
+.UL s
+command can be preceded by one or two `line numbers'
+to specify that the substitution is to take place
+on a group of lines.
+Thus
+.P1
+1,$s/mispell/misspell/
+.P2
+changes the
+.ul
+first
+occurrence of
+`mispell' to `misspell' on every line of the file.
+But
+.P1
+1,$s/mispell/misspell/g
+.P2
+changes
+.ul
+every
+occurrence in every line
+(and this is more likely to be what you wanted in this
+particular case).
+.PP
+You should also notice that if you add a
+.UL p
+or
+.UL l
+to the end of any of these substitute commands,
+only the last line that got changed will be printed,
+not all the lines.
+We will talk later about how to print all the lines
+that were modified.
+.SH
+The Undo Command `u'
+.PP
+Occasionally you will make a substitution in a line,
+only to realize too late that it was a ghastly mistake.
+The `undo' command
+.UL u
+lets you `undo' the last substitution:
+the last line that was substituted can be restored to
+its previous state by typing the command
+.P1
+u
+.P2
+.SH
+The Metacharacter `\*.'
+.PP
+As you have undoubtedly noticed
+when you use
+.UL ed ,
+certain characters have unexpected meanings
+when they occur in the left side of a substitute command,
+or in a search for a particular line.
+In the next several sections, we will talk about
+these special characters,
+which are often called `metacharacters'.
+.PP
+The first one is the period `\*.'.
+On the left side of a substitute command,
+or in a search with `/.../',
+`\*.' stands for
+.ul
+any
+single character.
+Thus the search
+.P1
+/x\*.y/
+.P2
+finds any line where `x' and `y' occur separated by
+a single character, as in
+.P1
+x+y
+x\-y
+x\*(BLy
+x\*.y
+.P2
+and so on.
+(We will use \*(BL to stand for a space whenever we need to
+make it visible.)
+.PP
+Since `\*.' matches a single character,
+that gives you a way to deal with funny characters
+printed by
+.UL l .
+Suppose you have a line that, when printed with the
+.UL l
+command, appears as
+.P1
+ .... th\*e07is ....
+.P2
+and you want to get rid of the
+\*e07
+(which represents the bell character, by the way).
+.PP
+The most obvious solution is to try
+.P1
+s/\*e07//
+.P2
+but this will fail. (Try it.)
+The brute force solution, which most people would now take,
+is to re-type the entire line.
+This is guaranteed, and is actually quite a reasonable tactic
+if the line in question isn't too big,
+but for a very long line,
+re-typing is a bore.
+This is where the metacharacter `\*.' comes in handy.
+Since `\*e07' really represents a single character,
+if we say
+.P1
+s/th\*.is/this/
+.P2
+the job is done.
+The `\*.' matches the mysterious character between the `h' and the `i',
+.UL "whatever it is" .
+.PP
+Bear in mind that since `\*.' matches any single character,
+the command
+.P1
+s/\*./,/
+.P2
+converts the first character on a line into a `,',
+which very often is not what you intended.
+.PP
+As is true of many characters in
+.UL ed ,
+the `\*.' has several meanings, depending
+on its context.
+This line shows all three:
+.P1
+\&\*.s/\*./\*./
+.P2
+The first `\*.' is a line number,
+the number of
+the line we are editing,
+which is called `line dot'.
+(We will discuss line dot more in Section 3.)
+The second `\*.' is a metacharacter
+that matches any single character on that line.
+The third `\*.' is the only one that really is
+an honest literal period.
+On the
+.ul
+right
+side of a substitution, `\*.'
+is not special.
+If you apply this command to the line
+.P1
+Now is the time\*.
+.P2
+the result will
+be
+.P1
+\&\*.ow is the time\*.
+.P2
+which is probably not what you intended.
+.SH
+The Backslash `\*e'
+.PP
+Since a period means `any character',
+the question naturally arises of what to do
+when you really want a period.
+For example, how do you convert the line
+.P1
+Now is the time\*.
+.P2
+into
+.P1
+Now is the time?
+.P2
+The backslash `\*e' does the job.
+A backslash turns off any special meaning that the next character
+might have; in particular,
+`\*e\*.' converts the `\*.' from a `match anything'
+into a period, so
+you can use it to replace
+the period in
+.P1
+Now is the time\*.
+.P2
+like this:
+.P1
+s/\*e\*./?/
+.P2
+The pair of characters `\*e\*.' is considered by
+.UL ed
+to be a single real period.
+.PP
+The backslash can also be used when searching for lines
+that contain a special character.
+Suppose you are looking for a line that contains
+.P1
+\&\*.PP
+.P2
+The search
+.P1
+/\*.PP/
+.P2
+isn't adequate, for it will find
+a line like
+.P1
+THE APPLICATION OF ...
+.P2
+because the `\*.' matches the letter `A'.
+But if you say
+.P1
+/\*e\*.PP/
+.P2
+you will find only lines that contain `\*.PP'.
+.PP
+The backslash can also be used to turn off special meanings for
+characters other than `\*.'.
+For example, consider finding a line that contains a backslash.
+The search
+.P1
+/\*e/
+.P2
+won't work,
+because the `\*e' isn't a literal `\*e', but instead means that the second `/'
+no longer \%delimits the search.
+But by preceding a backslash with another one,
+you can search for a literal backslash.
+Thus
+.P1
+/\*e\*e/
+.P2
+does work.
+Similarly, you can search for a forward slash `/' with
+.P1
+/\*e//
+.P2
+The backslash turns off the meaning of the immediately following `/' so that
+it doesn't terminate the /.../ construction prematurely.
+.PP
+As an exercise, before reading further, find two substitute commands each of which will
+convert the line
+.P1
+\*ex\*e\*.\*ey
+.P2
+into the line
+.P1
+\*ex\*ey
+.P2
+.PP
+Here are several solutions;
+verify that each works as advertised.
+.P1
+s/\*e\*e\*e\*.//
+s/x\*.\*./x/
+s/\*.\*.y/y/
+.P2
+.PP
+A couple of miscellaneous notes about
+backslashes and special characters.
+First, you can use any character to delimit the pieces
+of an
+.UL s
+command: there is nothing sacred about slashes.
+(But you must use slashes for context searching.)
+For instance, in a line that contains a lot of slashes already, like
+.P1
+//exec //sys.fort.go // etc...
+.P2
+you could use a colon as the delimiter _
+to delete all the slashes, type
+.P1
+s:/::g
+.P2
+.PP
+Second, if # and @ are your character erase and line kill characters,
+you have to type \*e# and \*e@;
+this is true whether you're talking to
+.UL ed
+or any other program.
+.PP
+When you are adding text with
+.UL a
+or
+.UL i
+or
+.UL c ,
+backslash is not special, and you should only put in
+one backslash for each one you really want.
+.SH
+The Dollar Sign `$'
+.PP
+The next metacharacter, the `$', stands for `the end of the line'.
+As its most obvious use, suppose you have the line
+.P1
+Now is the
+.P2
+and you wish to add the word `time' to the end.
+Use the $ like this:
+.P1
+s/$/\*(BLtime/
+.P2
+to get
+.P1
+Now is the time
+.P2
+Notice that a space is needed before `time' in
+the substitute command,
+or you will get
+.P1
+Now is thetime
+.P2
+.PP
+As another example, replace the second comma in
+the following line with a period without altering the first:
+.P1
+Now is the time, for all good men,
+.P2
+The command needed is
+.P1
+s/,$/\*./
+.P2
+The $ sign here provides context to make specific which comma we mean.
+Without it, of course, the
+.UL s
+command would operate on the first comma to produce
+.P1
+Now is the time\*. for all good men,
+.P2
+.PP
+As another example, to convert
+.P1
+Now is the time\*.
+.P2
+into
+.P1
+Now is the time?
+.P2
+as we did earlier, we can use
+.P1
+s/\*.$/?/
+.P2
+.PP
+Like `\*.', the `$'
+has multiple meanings depending on context.
+In the line
+.P1
+$s/$/$/
+.P2
+the first `$' refers to the
+last line of the file,
+the second refers to the end of that line,
+and the third is a literal dollar sign,
+to be added to that line.
+.SH
+The Circumflex `^'
+.PP
+The circumflex (or hat or caret)
+`^' stands for the beginning of the line.
+For example, suppose you are looking for a line that begins
+with `the'.
+If you simply say
+.P1
+/the/
+.P2
+you will in all likelihood find several lines that contain `the' in the middle before
+arriving at the one you want.
+But with
+.P1
+/^the/
+.P2
+you narrow the context, and thus arrive at the desired one
+more easily.
+.PP
+The other use of `^' is of course to enable you to insert
+something at the beginning of a line:
+.P1
+s/^/\*(BL/
+.P2
+places a space at the beginning of the current line.
+.PP
+Metacharacters can be combined. To search for a
+line that contains
+.ul
+only
+the characters
+.P1
+\&\*.PP
+.P2
+you can use the command
+.P1
+/^\*e\*.PP$/
+.P2
+.SH
+The Star `*'
+.PP
+Suppose you have a line that looks like this:
+.P1
+\fItext \fR x y \fI text \fR
+.P2
+where
+.ul
+text
+stands
+for lots of text,
+and there are some indeterminate number of spaces between the
+.UL x
+and the
+.UL y .
+Suppose the job is to replace all the spaces between
+.UL x
+and
+.UL y
+by a single space.
+The line is too long to retype, and there are too many spaces
+to count.
+What now?
+.PP
+This is where the metacharacter `*'
+comes in handy.
+A character followed by a star
+stands for as many consecutive occurrences of that
+character as possible.
+To refer to all the spaces at once, say
+.P1
+s/x\*(BL*y/x\*(BLy/
+.P2
+The construction
+`\*(BL*'
+means
+`as many spaces as possible'.
+Thus `x\*(BL*y' means `an x, as many spaces as possible, then a y'.
+.PP
+The star can be used with any character, not just space.
+If the original example was instead
+.P1
+\fItext \fR x--------y \fI text \fR
+.P2
+then all `\-' signs can be replaced by a single space
+with the command
+.P1
+s/x-*y/x\*(BLy/
+.P2
+.PP
+Finally, suppose that the line was
+.P1
+\fItext \fR x\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.y \fI text \fR
+.P2
+Can you see what trap lies in wait for the unwary?
+If you blindly type
+.P1
+s/x\*.*y/x\*(BLy/
+.P2
+what will happen?
+The answer, naturally, is that it depends.
+If there are no other x's or y's on the line,
+then everything works, but it's blind luck, not good management.
+Remember that `\*.' matches
+.ul
+any
+single character?
+Then `\*.*' matches as many single characters as possible,
+and unless you're careful, it can eat up a lot more of the line
+than you expected.
+If the line was, for example, like this:
+.P1
+\fItext \fRx\fI text \fR x\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.y \fI text \fRy\fI text \fR
+.P2
+then saying
+.P1
+s/x\*.*y/x\*(BLy/
+.P2
+will take everything from the
+.ul
+first
+`x' to the
+.ul
+last
+`y',
+which, in this example, is undoubtedly more than you wanted.
+.PP
+The solution, of course, is to turn off the special meaning of
+`\*.' with
+`\*e\*.':
+.P1
+s/x\*e\*.*y/x\*(BLy/
+.P2
+Now everything works, for `\*e\*.*' means `as many
+.ul
+periods
+as possible'.
+.PP
+There are times when the pattern `\*.*' is exactly what you want.
+For example, to change
+.P1
+Now is the time for all good men ....
+.P2
+into
+.P1
+Now is the time\*.
+.P2
+use `\*.*' to eat up everything after the `for':
+.P1
+s/\*(BLfor\*.*/\*./
+.P2
+.PP
+There are a couple of additional pitfalls associated with `*' that you should be aware of.
+Most notable is the fact that `as many as possible' means
+.ul
+zero
+or more.
+The fact that zero is a legitimate possibility is
+sometimes rather surprising.
+For example, if our line contained
+.P1
+\fItext \fR xy \fI text \fR x y \fI text \fR
+.P2
+and we said
+.P1
+s/x\*(BL*y/x\*(BLy/
+.P2
+the
+.ul
+first
+`xy' matches this pattern, for it consists of an `x',
+zero spaces, and a `y'.
+The result is that the substitute acts on the first `xy',
+and does not touch the later one that actually contains some intervening spaces.
+.PP
+The way around this, if it matters, is to specify a pattern like
+.P1
+/x\*(BL\*(BL*y/
+.P2
+which says `an x, a space, then as many more spaces as possible, then a y',
+in other words, one or more spaces.
+.SH
+The Brackets `[ ]'
+.PP
+Suppose that you want to delete any numbers
+that appear
+at the beginning of all lines of a file.
+You might first think of trying a series of commands like
+.P1
+1,$s/^1*//
+1,$s/^2*//
+1,$s/^3*//
+.P2
+and so on,
+but this is clearly going to take forever if the numbers are at all long.
+Unless you want to repeat the commands over and over until
+finally all numbers are gone,
+you must get all the digits on one pass.
+This is the purpose of the brackets [ and ].
+.PP
+The construction
+.P1
+[0123456789]
+.P2
+matches any single digit _
+the whole thing is called a `character class'.
+With a character class, the job is easy.
+The pattern `[0123456789]*' matches zero or more digits (an entire number), so
+.P1
+1,$s/^[0123456789]*//
+.P2
+deletes all digits from the beginning of all lines.
+.PP
+Any characters can appear within a character class,
+and just to confuse the issue there are essentially no special characters
+inside the brackets;
+even the backslash doesn't have a special meaning.
+To search for special characters, for example, you can say
+.P1
+/[\*.\*e$^[]/
+.P2
+Within [...], the `[' is not special.
+To get a `]' into a character class,
+make it the first character.
+.PP
+It's a nuisance to have to spell out the digits,
+so you can abbreviate them as
+[0\-9];
+similarly, [a\-z] stands for the lower case letters,
+and
+[A\-Z] for upper case.
+.PP
+As a final frill on character classes, you can specify a class
+that means `none of the following characters'.
+This is done by beginning the class with a `^':
+.P1
+[^0-9]
+.P2
+stands for `any character
+.ul
+except
+a digit'.
+Thus you might find the first line that doesn't begin with a tab or space
+by a search like
+.P1
+/^[^(space)(tab)]/
+.P2
+.PP
+Within a character class,
+the circumflex has a special meaning
+only if it occurs at the beginning.
+Just to convince yourself, verify that
+.P1
+/^[^^]/
+.P2
+finds a line that doesn't begin with a circumflex.
+.SH
+The Ampersand `&'
+.PP
+The ampersand `&' is used primarily to save typing.
+Suppose you have the line
+.P1
+Now is the time
+.P2
+and you want to make it
+.P1
+Now is the best time
+.P2
+Of course you can always say
+.P1
+s/the/the best/
+.P2
+but it seems silly to have to repeat the `the'.
+The `&' is used to eliminate the repetition.
+On the
+.ul
+right
+side of a substitute, the ampersand means `whatever
+was just matched', so you can say
+.P1
+s/the/& best/
+.P2
+and the `&' will stand for `the'.
+Of course this isn't much of a saving if the thing
+matched is just `the', but if it is something truly long or awful,
+or if it is something like `.*'
+which matches a lot of text,
+you can save some tedious typing.
+There is also much less chance of making a typing error
+in the replacement text.
+For example, to parenthesize a line,
+regardless of its length,
+.P1
+s/\*.*/(&)/
+.P2
+.PP
+The ampersand can occur more than once on the right side:
+.P1
+s/the/& best and & worst/
+.P2
+makes
+.P1
+Now is the best and the worst time
+.P2
+and
+.P1
+s/\*.*/&? &!!/
+.P2
+converts the original line into
+.P1
+Now is the time? Now is the time!!
+.P2
+.PP
+To get a literal ampersand, naturally the backslash is used to turn off the special meaning:
+.P1
+s/ampersand/\*e&/
+.P2
+converts the word into the symbol.
+Notice that `&' is not special on the left side
+of a substitute, only on the
+.ul
+right
+side.
+.SH
+Substituting Newlines
+.PP
+.UL ed
+provides a facility for splitting a single line into two or more shorter lines by `substituting in a newline'.
+As the simplest example, suppose a line has gotten unmanageably long
+because of editing (or merely because it was unwisely typed).
+If it looks like
+.P1
+\fItext \fR xy \fI text \fR
+.P2
+you can break it between the `x' and the `y' like this:
+.P1
+s/xy/x\*e
+y/
+.P2
+This is actually a single command,
+although it is typed on two lines.
+Bearing in mind that `\*e' turns off special meanings,
+it seems relatively intuitive that a `\*e' at the end of
+a line would make the newline there
+no longer special.
+.PP
+You can in fact make a single line into several lines
+with this same mechanism.
+As a large example, consider underlining the word `very'
+in a long line
+by splitting `very' onto a separate line,
+and preceding it by the
+.UL roff
+or
+.UL nroff
+formatting command `.ul'.
+.P1
+\fItext \fR a very big \fI text \fR
+.P2
+The command
+.P1
+s/\*(BLvery\*(BL/\*e
+\&.ul\*e
+very\*e
+/
+.P2
+converts the line into four shorter lines,
+preceding the word `very' by the
+line
+`.ul',
+and eliminating the spaces around the `very',
+all at the same time.
+.PP
+When a newline is substituted
+in, dot is left pointing at the last line created.
+.PP
+.SH
+Joining Lines
+.PP
+Lines may also be joined together,
+but this is done with the
+.UL j
+command
+instead of
+.UL s .
+Given the lines
+.P1
+Now is
+\*(BLthe time
+.P2
+and supposing that dot is set to the first of them,
+then the command
+.P1
+j
+.P2
+joins them together.
+No blanks are added,
+which is why we carefully showed a blank
+at the beginning of the second line.
+.PP
+All by itself,
+a
+.UL j
+command
+joins line dot to line dot+1,
+but any contiguous set of lines can be joined.
+Just specify the starting and ending line numbers.
+For example,
+.P1
+1,$jp
+.P2
+joins all the lines into one big one
+and prints it.
+(More on line numbers in Section 3.)
+.SH
+Rearranging a Line with \*e( ... \*e)
+.PP
+(This section should be skipped on first reading.)
+Recall that `&' is a shorthand that stands for whatever
+was matched by the left side of an
+.UL s
+command.
+In much the same way you can capture separate pieces
+of what was matched;
+the only difference is that you have to specify
+on the left side just what pieces you're interested in.
+.PP
+Suppose, for instance, that
+you have a file of lines that consist of names in the form
+.P1
+Smith, A. B.
+Jones, C.
+.P2
+and so on,
+and you want the initials to precede the name, as in
+.P1
+A. B. Smith
+C. Jones
+.P2
+It is possible to do this with a series of editing commands,
+but it is tedious and error-prone.
+(It is instructive to figure out how it is done, though.)
+.PP
+The alternative
+is to `tag' the pieces of the pattern (in this case,
+the last name, and the initials),
+and then rearrange the pieces.
+On the left side of a substitution,
+if part of the pattern is enclosed between
+\*e( and \*e),
+whatever matched that part is remembered,
+and available for use on the right side.
+On the right side,
+the symbol `\*e1' refers to whatever
+matched the first \*e(...\*e) pair,
+`\*e2' to the second \*e(...\*e),
+and so on.
+.PP
+The command
+.P1
+1,$s/^\*e([^,]*\*e),\*(BL*\*e(\*.*\*e)/\*e2\*(BL\*e1/
+.P2
+although hard to read, does the job.
+The first \*e(...\*e) matches the last name,
+which is any string up to the comma;
+this is referred to on the right side with `\*e1'.
+The second \*e(...\*e) is whatever follows
+the comma and any spaces,
+and is referred to as `\*e2'.
+.PP
+Of course, with any editing sequence this complicated,
+it's foolhardy to simply run it and hope.
+The global commands
+.UL g
+and
+.UL v
+discussed in section 4
+provide a way for you to print exactly those
+lines which were affected by the
+substitute command,
+and thus verify that it did what you wanted
+in all cases.
diff --git a/bin/ed/USD.doc/10.edadv/ae3 b/bin/ed/USD.doc/10.edadv/ae3
new file mode 100644
index 0000000..92ef639
--- /dev/null
+++ b/bin/ed/USD.doc/10.edadv/ae3
@@ -0,0 +1,488 @@
+.\" $OpenBSD: ae3,v 1.4 2004/04/06 08:19:20 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)ae3 8.1 (Berkeley) 6/8/93
+.\"
+.NH
+LINE ADDRESSING IN THE EDITOR
+.PP
+The next general area we will discuss is that of
+line addressing in
+.UL ed ,
+that is, how you specify what lines are to be
+affected by editing commands.
+We have already used constructions like
+.P1
+1,$s/x/y/
+.P2
+to specify a change on all lines.
+And most users are long since familiar with
+using a single newline (or return) to print the next line,
+and with
+.P1
+/thing/
+.P2
+to find a line that contains `thing'.
+Less familiar, surprisingly enough, is the
+use of
+.P1
+?thing?
+.P2
+to scan
+.ul
+backwards
+for the previous occurrence of `thing'.
+This is especially handy when you realize that the thing
+you want to operate on is back up the page from
+where you are currently editing.
+.PP
+The slash and question mark are the only characters you can
+use to delimit a context search, though you can use
+essentially any character in a substitute command.
+.SH
+Address Arithmetic
+.PP
+The next step is to combine the line numbers
+like `\*.', `$', `/.../' and `?...?'
+with `+' and `\-'.
+Thus
+.P1
+$-1
+.P2
+is a command to print the next to last line of
+the current file (that is, one line before line `$').
+For example, to recall how far you got in a previous editing session,
+.P1
+$-5,$p
+.P2
+prints the last six lines.
+(Be sure you understand why it's six, not five.)
+If there aren't six, of course, you'll get an error message.
+.PP
+As another example,
+.P1
+\&\*.-3,\*.+3p
+.P2
+prints from three lines before where you are now
+(at line dot)
+to three lines after,
+thus giving you a bit of context.
+.PP
+Another area in which you can save typing effort
+in specifying lines is to use `\-' and `+' as line numbers
+by themselves.
+.P1
+-
+.P2
+by itself is a command to move back up one line in the file.
+In fact, you can string several minus signs together to move
+back up that many lines:
+.P1
+---
+.P2
+moves up three lines, as does `\-3'.
+Thus
+.P1
+-3,+3p
+.P2
+is also identical to the examples above.
+.PP
+Since `\-' is shorter than `\*.\-1',
+constructions like
+.P1
+-,\*.s/bad/good/
+.P2
+are useful. This changes `bad' to `good' on the previous line and
+on the current line.
+.PP
+`+' and `\-' can be used in combination with searches using `/.../' and `?...?',
+and with `$'.
+The search
+.P1
+/thing/--
+.P2
+finds the line containing `thing', and positions you
+two lines before it.
+.SH
+Repeated Searches
+.PP
+Suppose you ask for the search
+.P1
+/horrible thing/
+.P2
+and when the line is printed you discover that it
+isn't the horrible thing that you wanted,
+so it is necessary to repeat the search again.
+You don't have to re-type the search,
+for the construction
+.P1
+//
+.P2
+is a shorthand for `the previous thing that was searched for',
+whatever it was.
+This can be repeated as many times as necessary.
+You can also go backwards:
+.P1
+??
+.P2
+searches for the same thing,
+but in the reverse direction.
+.PP
+Not only can you repeat the search, but you can
+use `//' as the left side of a substitute command,
+to mean
+`the most recent pattern'.
+.P1
+/horrible thing/
+.ft I
+ .... ed prints line with `horrible thing' ...
+.ft R
+s//good/p
+.P2
+To go backwards and change a line, say
+.P1
+??s//good/
+.P2
+Of course, you can still use the `&' on the right hand side of a substitute to stand for
+whatever got matched:
+.P1
+//s//&\*(BL&/p
+.P2
+finds the next occurrence of whatever you searched for last,
+replaces it by two copies of itself,
+then prints the line just to verify that it worked.
+.SH
+Default Line Numbers and the Value of Dot
+.PP
+One of the most effective ways to speed up your editing
+is always to know what lines will be affected
+by a command if you don't specify the lines it is to act on,
+and on what line you will be positioned (i.e., the value of dot) when a command finishes.
+If you can edit without specifying unnecessary
+line numbers, you can save a lot of typing.
+.PP
+As the most obvious example, if you issue a search command
+like
+.P1
+/thing/
+.P2
+you are left pointing at the next line that contains `thing'.
+Then no address is required with commands like
+.UL s
+to make a substitution on that line,
+or
+.UL p
+to print it,
+or
+.UL l
+to list it,
+or
+.UL d
+to delete it,
+or
+.UL a
+to append text after it,
+or
+.UL c
+to change it,
+or
+.UL i
+to insert text before it.
+.PP
+What happens if there was no `thing'?
+Then you are left right where you were _
+dot is unchanged.
+This is also true if you were sitting
+on the only `thing' when you issued the command.
+The same rules hold for searches that use
+`?...?'; the only difference is the direction
+in which you search.
+.PP
+The delete command
+.UL d
+leaves dot pointing
+at the line that followed the last deleted line.
+When line `$' gets deleted,
+however,
+dot points at the
+.ul
+new
+line `$'.
+.PP
+The line-changing commands
+.UL a ,
+.UL c ,
+and
+.UL i
+by default all affect the current line _
+if you give no line number with them,
+.UL a
+appends text after the current line,
+.UL c
+changes the current line,
+and
+.UL i
+inserts text before the current line.
+.PP
+.UL a ,
+.UL c ,
+and
+.UL i
+behave identically in one respect _
+when you stop appending, changing, or inserting,
+dot points at the last line entered.
+This is exactly what you want for typing and editing on the fly.
+For example, you can say
+.P1
+.ta 1.5i
+a
+ ... text ...
+ ... botch ... (minor error)
+\&\*.
+s/botch/correct/ (fix botched line)
+a
+ ... more text ...
+.P2
+without specifying any line number for the substitute command or for
+the second append command.
+Or you can say
+.P1 2
+.ta 1.5i
+a
+ ... text ...
+ ... horrible botch ... (major error)
+\&\*.
+c (replace entire line)
+ ... fixed up line ...
+.P2
+.PP
+You should experiment to determine what happens if you add
+.ul
+no
+lines with
+.UL a ,
+.UL c ,
+or
+.UL i .
+.PP
+The
+.UL r
+command will read a file into the text being edited,
+either at the end if you give no address,
+or after the specified line if you do.
+In either case, dot points at the last line read in.
+Remember that you can even say
+.UL 0r
+to read a file in at the beginning of the text.
+(You can also say
+.UL 0a
+or
+.UL 1i
+to start adding text at the beginning.)
+.PP
+The
+.UL w
+command writes out the entire file.
+If you precede the command by one line number,
+that line is written,
+while if you precede it by two line numbers,
+that range of lines is written.
+The
+.UL w
+command does
+.ul
+not
+change dot:
+the current line remains the same,
+regardless of what lines are written.
+This is true even if you say something like
+.P1
+/^\*e\*.AB/,/^\*e\*.AE/w abstract
+.P2
+which involves a context search.
+.PP
+Since the
+.UL w
+command is so easy to use,
+you should save what you are editing regularly
+as you go along
+just in case the system crashes, or in case you do something foolish,
+like clobbering what you're editing.
+.PP
+The least intuitive behavior, in a sense, is that of the
+.UL s
+command.
+The rule is simple _
+you are left sitting on the last line that got changed.
+If there were no changes, then dot is unchanged.
+.PP
+To illustrate,
+suppose that there are three lines in the buffer, and you are sitting on
+the middle one:
+.P1
+x1
+x2
+x3
+.P2
+Then the command
+.P1
+\&-,+s/x/y/p
+.P2
+prints the third line, which is the last one changed.
+But if the three lines had been
+.P1
+x1
+y2
+y3
+.P2
+and the same command had been issued while
+dot pointed
+at the second line, then the result
+would be to change and print only the first line,
+and that is where dot would be set.
+.SH
+Semicolon `;'
+.PP
+Searches with `/.../' and `?...?' start
+at the current line and move
+forward or backward respectively
+until they either find the pattern or get back to the current line.
+Sometimes this is not what is wanted.
+Suppose, for example, that the buffer contains lines like this:
+.P1
+ \*.
+ \*.
+ \*.
+ ab
+ \*.
+ \*.
+ \*.
+ bc
+ \*.
+ \*.
+.P2
+Starting at line 1, one would expect that the command
+.P1
+/a/,/b/p
+.P2
+prints all the lines from the `ab' to the `bc' inclusive.
+Actually this is not what happens.
+.ul
+Both
+searches
+(for `a' and for `b')
+start from the same point, and thus they both find the line
+that contains `ab'.
+The result is to print a single line.
+Worse, if there had been a line with a `b' in it
+before the `ab' line, then the print command
+would be in error, since the second line number
+would be less than the first, and it is illegal to
+try to print lines in reverse order.
+.PP
+This is because the comma separator
+for line numbers doesn't set dot as each address is processed;
+each search starts from the same place.
+In
+.UL ed ,
+the semicolon `;' can be used just like comma,
+with the single difference that use of a semicolon
+forces dot to be set at that point
+as the line numbers are being evaluated.
+In effect, the semicolon `moves' dot.
+Thus in our example above, the command
+.P1
+/a/;/b/p
+.P2
+prints the range of lines from `ab' to `bc',
+because after the `a' is found, dot is set to that line,
+and then `b' is searched for, starting beyond that line.
+.PP
+This property is most often useful in a very simple situation.
+Suppose you want to find the
+.ul
+second
+occurrence of `thing'.
+You could say
+.P1
+/thing/
+//
+.P2
+but this prints the first occurrence as well as the second,
+and is a nuisance when you know very well that it is only
+the second one you're interested in.
+The solution is to say
+.P1
+/thing/;//
+.P2
+This says to find the first occurrence of `thing', set dot to that line, then find the second
+and print only that.
+.PP
+Closely related is searching for the second previous
+occurrence of something, as in
+.P1
+?something?;??
+.P2
+Printing the third or fourth or ...
+in either direction is left as an exercise.
+.PP
+Finally, bear in mind that if you want to find the first occurrence of
+something in a file, starting at an arbitrary place within the file,
+it is not sufficient to say
+.P1
+1;/thing/
+.P2
+because this fails if `thing' occurs on line 1.
+But it is possible to say
+.P1
+0;/thing/
+.P2
+(one of the few places where 0 is a legal line number),
+for this starts the search at line 1.
+.SH
+Interrupting the Editor
+.PP
+As a final note on what dot gets set to,
+you should be aware that if you hit the interrupt or delete
+or rubout or break key
+while
+.UL ed
+is doing a command, things are put back together again and your state
+is restored as much as possible to what it was before the command
+began.
+Naturally, some changes are irrevocable _
+if you are reading or writing a file or making substitutions or deleting lines, these will be stopped
+in some clean but unpredictable state in the middle
+(which is why it is not usually wise to stop them).
+Dot may or may not be changed.
diff --git a/bin/ed/USD.doc/10.edadv/ae4 b/bin/ed/USD.doc/10.edadv/ae4
new file mode 100644
index 0000000..05d2d3a
--- /dev/null
+++ b/bin/ed/USD.doc/10.edadv/ae4
@@ -0,0 +1,218 @@
+.\" $OpenBSD: ae4,v 1.3 2004/04/06 08:19:20 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)ae4 8.1 (Berkeley) 6/8/93
+.\"
+.NH
+GLOBAL COMMANDS
+.PP
+The global commands
+.UL g
+and
+.UL v
+are used to perform one or more editing commands on all lines that either
+contain
+.UL g ) (
+or don't contain
+.UL v ) (
+a specified pattern.
+.PP
+As the simplest example, the command
+.P1
+g/UNIX/p
+.P2
+prints all lines that contain the word `UNIX'.
+The pattern that goes between the slashes can be anything
+that could be used in a line search or in a substitute command;
+exactly the same rules and limitations apply.
+.PP
+As another example, then,
+.P1
+g/^\*e\*./p
+.P2
+prints all the formatting commands in a file (lines that begin with `\*.').
+.PP
+The
+.UL v
+command is identical to
+.UL g ,
+except that it operates on those line that do
+.ul
+not
+contain an occurrence of the pattern.
+(Don't look too hard for mnemonic significance to
+the letter `v'.)
+So
+.P1
+v/^\*e\*./p
+.P2
+prints all the lines that don't begin with `\*.' _
+the actual text lines.
+.PP
+The command that follows
+.UL g
+or
+.UL v
+can be anything:
+.P1
+g/^\*e\*./d
+.P2
+deletes all lines that begin with `\*.',
+and
+.P1
+g/^$/d
+.P2
+deletes all empty lines.
+.PP
+Probably the most useful command that can follow a global is the
+substitute command, for this can be used to make a change
+and print each affected line for verification.
+For example, we could change the word `Unix' to `UNIX'
+everywhere, and verify that
+it really worked,
+with
+.P1
+g/Unix/s//UNIX/gp
+.P2
+Notice that we used `//' in the substitute command to mean
+`the previous pattern', in this case, `Unix'.
+The
+.UL p
+command is done on every line
+that matches the pattern,
+not just those on which a substitution took place.
+.PP
+The global command operates by making
+two passes over the file.
+On the first pass, all lines that match the pattern are marked.
+On the second pass, each marked line in turn is examined,
+dot is set to that line, and the command executed.
+This means that it is possible for the command that follows a
+.UL g
+or
+.UL v
+to use addresses, set dot, and so on, quite freely.
+.P1
+g/^\*e\*.PP/+
+.P2
+prints the line that follows each `.PP' command (the signal for
+a new paragraph in some formatting packages).
+Remember that `+' means `one line past dot'.
+And
+.P1
+g/topic/?^\*e\*.SH?1
+.P2
+searches for each line that contains `topic', scans backwards until it finds
+a line that begins `.SH' (a section heading) and prints the line
+that follows that,
+thus showing the section headings under which `topic' is mentioned.
+Finally,
+.P1
+g/^\*e\*.EQ/+,/^\*e\*.EN/-p
+.P2
+prints all the lines that lie between
+lines beginning with `.EQ' and `.EN' formatting commands.
+.PP
+The
+.UL g
+and
+.UL v
+commands can also be
+preceded by line numbers, in which case the lines searched
+are only those in the range specified.
+.SH
+Multi-line Global Commands
+.PP
+It is possible to do more than one command under the control of a
+global command, although the syntax for expressing the operation
+is not especially natural or pleasant.
+As an example,
+suppose the task is to change `x' to `y' and `a' to `b' on all lines
+that contain `thing'.
+Then
+.P1
+g/thing/s/x/y/\*e
+s/a/b/
+.P2
+is sufficient.
+The `\*e' signals the
+.UL g
+command that the set of commands continues on the next line;
+it terminates on the first line that does not end with `\*e'.
+(As a minor blemish, you can't use a substitute command
+to insert a newline within a
+.UL g
+command.)
+.PP
+You should watch out for this problem:
+the command
+.P1
+g/x/s//y/\*e
+s/a/b/
+.P2
+does
+.ul
+not
+work as you expect.
+The remembered pattern is the last pattern that was actually
+executed,
+so sometimes it will be
+`x' (as expected), and sometimes it will be `a'
+(not expected).
+You must spell it out, like this:
+.P1
+g/x/s/x/y/\*e
+s/a/b/
+.P2
+.PP
+It is also possible to execute
+.UL a ,
+.UL c ,
+and
+.UL i
+commands under a global command; as with other multi-line constructions,
+all that is needed is to add a `\*e' at the end of each line except the last.
+Thus to add a `.nf' and `.sp' command before each `.EQ' line, type
+.P1
+g/^\*e\*.EQ/i\*e
+\&\*.nf\*e
+\&\*.sp
+.P2
+There is no need for a final line containing a
+`\*.' to terminate the
+.UL i
+command,
+unless there are further commands
+being done under the global.
+On the other hand, it does no harm to put it in either.
diff --git a/bin/ed/USD.doc/10.edadv/ae5 b/bin/ed/USD.doc/10.edadv/ae5
new file mode 100644
index 0000000..65b6f9a
--- /dev/null
+++ b/bin/ed/USD.doc/10.edadv/ae5
@@ -0,0 +1,359 @@
+.\" $OpenBSD: ae5,v 1.2 2003/06/26 16:24:16 mickey Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)ae5 8.1 (Berkeley) 8/14/93
+.\"
+.NH
+CUT AND PASTE WITH UNIX COMMANDS
+.PP
+One editing area in which non-programmers
+seem not very confident
+is in what might be called
+`cut and paste' operations _
+changing the name of a file,
+making a copy of a file somewhere else,
+moving a few lines from one place to another in a file,
+inserting one file in the middle of another,
+splitting a file into pieces,
+and
+splicing two or more files together.
+.PP
+Yet most of these operations are actually quite easy,
+if you keep your wits about you
+and go cautiously.
+The next several sections talk about cut and paste.
+We will begin with the
+.UX
+commands
+for moving entire files around,
+then discuss
+.UL ed
+commands
+for operating on pieces of files.
+.SH
+Changing the Name of a File
+.PP
+You have a file named
+`memo'
+and you want it to be called
+`paper'
+instead.
+How is it done?
+.PP
+The
+.UX
+program that renames files
+is called
+.UL mv
+(for `move');
+it `moves' the file from one name to another, like this:
+.P1
+mv memo paper
+.P2
+That's all there is to it:
+.UL mv
+from the old name to the new name.
+.P1
+mv oldname newname
+.P2
+Warning: if there is already a file around with the new name,
+its present contents will be
+silently
+clobbered
+by the information from the other file.
+The one exception is that you can't move a file
+to itself _
+.P1
+mv x x
+.P2
+is illegal.
+.SH
+Making a Copy of a File
+.PP
+Sometimes what you want is a copy of a file _
+an entirely fresh version.
+This might be because you want to work on a file, and
+yet save a copy in case something gets fouled up,
+or just because you're paranoid.
+.PP
+In any case, the way to do it is with the
+.UL cp
+command.
+.UL cp \& (
+stands for `copy';
+the
+UNIX
+system
+is big on short command names,
+which are appreciated by heavy users,
+but sometimes a strain for novices.)
+Suppose you have a file called
+`good'
+and
+you want to save a copy before you make some
+dramatic editing changes.
+Choose a name _
+`savegood'
+might be acceptable _ then type
+.P1
+cp good savegood
+.P2
+This copies
+`good'
+onto
+`savegood',
+and you now have two identical copies of the file
+`good'.
+(If
+`savegood'
+previously contained something,
+it gets overwritten.)
+.PP
+Now if you decide at some time that you want to get
+back to the original state of
+`good',
+you can say
+.P1
+mv savegood good
+.P2
+(if you're not interested in
+`savegood'
+any more), or
+.P1
+cp savegood good
+.P2
+if you still want to retain a safe copy.
+.PP
+In summary,
+.UL mv
+just renames a file;
+.UL cp
+makes a duplicate copy.
+Both of them clobber the `target' file
+if it already exists, so you had better
+be sure that's what you want to do
+.ul
+before
+you do it.
+.SH
+Removing a File
+.PP
+If you decide you are really done with a file
+forever, you can remove it
+with the
+.UL rm
+command:
+.P1
+rm savegood
+.P2
+throws away (irrevocably) the file called
+`savegood'.
+.SH
+Putting Two or More Files Together
+.PP
+The next step is the familiar one of collecting two or more
+files into one big one.
+This will be needed, for example,
+when the author of a paper
+decides that several sections need to be combined
+into one.
+There are several ways to do it,
+of which the cleanest, once you get used to it,
+is a program called
+.UL cat .
+(Not
+.ul
+all
+UNIX
+programs have two-letter names.)
+.UL cat
+is short for
+`concatenate', which is exactly
+what we want to do.
+.PP
+Suppose the job is to combine the files
+`file1'
+and
+`file2'
+into a single file called
+`bigfile'.
+If you say
+.P1
+cat file
+.P2
+the contents of
+`file'
+will get printed on your terminal.
+If you say
+.P1
+cat file1 file2
+.P2
+the contents of
+`file1'
+and then the contents of
+`file2'
+will
+.ul
+both
+be printed on your terminal,
+in that order.
+So
+.UL cat
+combines the files, all right,
+but it's not much help to print them on the terminal _
+we want them in
+`bigfile'.
+.PP
+Fortunately, there is a way.
+You can tell
+the system
+that instead of printing on your terminal,
+you want the same information put in a file.
+The way to do it is to add to the command line
+the character
+.UL >
+and the name of the file
+where you want the output to go.
+Then you can say
+.P1
+cat file1 file2 >bigfile
+.P2
+and the job is done.
+(As with
+.UL cp
+and
+.UL mv ,
+you're putting something into
+`bigfile',
+and anything that was already there is destroyed.)
+.PP
+This ability to
+`capture' the output of a program
+is one of the most useful aspects of
+the
+UNIX
+system.
+Fortunately it's not limited to the
+.UL cat
+program _
+you can use it with
+.ul
+any
+program that prints on your terminal.
+We'll see some more uses for it in a moment.
+.PP
+Naturally, you can combine several files,
+not just two:
+.P1
+cat file1 file2 file3 ... >bigfile
+.P2
+collects a whole bunch.
+.PP
+Question:
+is there any difference between
+.P1
+cp good savegood
+.P2
+and
+.P1
+cat good >savegood
+.P2
+Answer: for most purposes, no.
+You might reasonably ask why there are two programs
+in that case,
+since
+.UL cat
+is obviously all you need.
+The answer is that
+.UL cp
+can do some other things as well,
+which you can investigate for yourself
+by reading the manual.
+For now we'll stick to simple usages.
+.SH
+Adding Something to the End of a File
+.PP
+Sometimes you want to add one file to the end of another.
+We have enough building blocks now that you can do it;
+in fact before reading further it would be valuable
+if you figured out how.
+To be specific,
+how would you use
+.UL cp ,
+.UL mv
+and/or
+.UL cat
+to add the file
+`good1'
+to the end of the file
+`good'?
+.PP
+You could try
+.P1
+cat good good1 >temp
+mv temp good
+.P2
+which is probably most direct.
+You should also understand why
+.P1
+cat good good1 >good
+.P2
+doesn't work.
+(Don't practice with a good `good'!)
+.PP
+The easy way is to use a variant of
+.UL > ,
+called
+.UL >> .
+In fact,
+.UL >>
+is identical to
+.UL >
+except that instead of clobbering the old file,
+it simply tacks stuff on at the end.
+Thus you could say
+.P1
+cat good1 >>good
+.P2
+and
+`good1'
+is added to the end of
+`good'.
+(And if
+`good'
+didn't exist,
+this makes a copy of
+`good1'
+called
+`good'.)
diff --git a/bin/ed/USD.doc/10.edadv/ae6 b/bin/ed/USD.doc/10.edadv/ae6
new file mode 100644
index 0000000..0917484
--- /dev/null
+++ b/bin/ed/USD.doc/10.edadv/ae6
@@ -0,0 +1,519 @@
+.\" $OpenBSD: ae6,v 1.4 2004/04/06 08:19:20 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)ae6 8.1 (Berkeley) 6/8/93
+.\"
+.NH
+CUT AND PASTE WITH THE EDITOR
+.PP
+Now we move on to manipulating pieces of files _
+individual lines or groups of lines.
+This is another area where new users seem
+unsure of themselves.
+.SH
+Filenames
+.PP
+The first step is to ensure that you know the
+.UL ed
+commands for reading and writing files.
+Of course you can't go very far without knowing
+.UL r
+and
+.UL w .
+Equally useful, but less well known, is the `edit' command
+.UL e .
+Within
+.UL ed ,
+the command
+.P1
+e newfile
+.P2
+says `I want to edit a new file called
+.UL newfile ,
+without leaving the editor.'
+The
+.UL e
+command discards whatever you're currently working on
+and starts over on
+.UL newfile .
+It's exactly the same as if you had quit with the
+.UL q
+command, then re-entered
+.UL ed
+with a new file name,
+except that if you have a pattern remembered, then a command
+like
+.UL //
+will still work.
+.PP
+If you enter
+.UL ed
+with the command
+.P1
+ed file
+.P2
+.UL ed
+remembers the name of the file,
+and any subsequent
+.UL e ,
+.UL r ,
+or
+.UL w
+commands that don't contain a filename
+will refer to this remembered file.
+Thus
+.P1 2
+.ta .5i .6i .7i
+ed file1
+ ... (editing) ...
+w (writes back in file1)
+e file2 (edit new file, without leaving editor)
+ ... (editing on file2) ...
+w (writes back on file2)
+.P2
+(and so on) does a series of edits on various files
+without ever leaving
+.UL ed
+and without typing the name of any file more than once.
+(As an aside, if you examine the sequence of commands here,
+you can see why many
+UNIX
+systems use
+.UL e
+as a synonym
+for
+.UL ed .)
+.PP
+You can find out the remembered file name at any time
+with the
+.UL f
+command;
+just type
+.UL f
+without a file name.
+You can also change the name of the remembered file name with
+.UL f ;
+a useful sequence is
+.P1
+ed precious
+f junk
+ ... (editing) ...
+.P2
+which gets a copy of a precious file,
+then uses
+.UL f
+to guarantee that a careless
+.UL w
+command won't clobber the original.
+.SH
+Inserting One File into Another
+.PP
+Suppose you have a file called
+`memo',
+and you want the file called
+`table'
+to be inserted just after the reference to
+Table 1.
+That is, in
+`memo'
+somewhere is a line that says
+.IP
+Table 1 shows that ...
+.LP
+and the data contained in
+`table'
+has to go there,
+probably so it will be formatted
+properly by
+.UL nroff
+or
+.UL troff .
+Now what?
+.PP
+This one is easy.
+Edit
+`memo',
+find
+`Table 1',
+and add the file
+`table'
+right there:
+.P1
+ed memo
+/Table 1/
+.ft I
+Table 1 shows that ... [response from ed]
+.ft
+\&\*.r table
+.P2
+The critical line is the last one.
+As we said earlier, the
+.UL r
+command reads a file;
+here you asked for it to be read in right after
+line dot.
+An
+.UL r
+command without any address
+adds lines at the end,
+so it is the same as
+.UL $r .
+.SH
+Writing out Part of a File
+.PP
+The other side of the coin is writing out part of
+the document you're editing.
+For example, maybe
+you want to copy out into a separate file
+that table from the previous example,
+so it can be formatted and tested separately.
+Suppose that in the file being edited
+we have
+.P1
+\&\*.TS
+ ...[lots of stuff]
+\&\*.TE
+.P2
+which is the way a table is set up for the
+.UL tbl
+program.
+To isolate
+the table
+in a separate file called
+`table',
+first find the start of the table
+(the `.TS' line), then write out the interesting part:
+.P1
+/^\*e\*.TS/
+.ft I
+\&\*.TS [ed prints the line it found]
+.ft R
+\&\*.,/^\*e\*.TE/w table
+.P2
+and the job is done.
+If you are confident, you can do it all at once with
+.P1
+/^\*e\*.TS/;/^\*e\*.TE/w table
+.P2
+and now you have two copies, one in the file you're still editing,
+one in the file `table' you've just written.
+.PP
+The point is that the
+.UL w
+command can
+write out a group of lines, instead of the whole file.
+In fact, you can write out a single line if you like:
+just give one line number instead of two.
+For example, if you have just typed a horribly complicated line
+and you know that it (or something like it) is going to be needed later,
+then save it _ don't re-type it.
+In the editor, say
+.P1
+a
+\&...lots of stuff...
+\&...horrible line...
+\&\*.
+\&\*.w temp
+a
+\&\*.\*.\*.more stuff\*.\*.\*.
+\&\*.
+\&\*.r temp
+a
+\&\*.\*.\*.more stuff\*.\*.\*.
+\&\*.
+.P2
+This last example is worth studying, to be sure you appreciate
+what's going on.
+.SH
+Moving Lines Around
+.PP
+Suppose you want to
+move a paragraph from its present position in a paper
+to the end.
+How would you do it?
+As a concrete example, suppose each paragraph in the paper
+begins with the formatting command
+`.PP'.
+Think about it and write down the details before reading on.
+.PP
+The brute force way
+(not necessarily bad)
+is to write the paragraph onto a temporary file,
+delete it from its current position,
+then read in the temporary file at the end.
+Assuming that you are sitting on the
+`.PP' command that begins
+the paragraph, this is the sequence of commands:
+.P1
+\&\*.,/^\*e\*.PP/-w temp
+\&\*.,//-d
+$r temp
+.P2
+That is, from where you are now
+(`\*.')
+until one line before the next `\*.PP'
+(`/^\*e\*.PP/\-')
+write onto
+`temp'.
+Then delete the same lines.
+Finally, read
+`temp'
+at the end.
+.PP
+As we said, that's the brute force way.
+The easier way (often)
+is to use the
+.ul
+move
+command
+.UL m
+that
+.UL ed
+provides _
+it lets you do the whole set of operations
+at one crack,
+without any temporary file.
+.PP
+The
+.UL m
+command
+is like many other
+.UL ed
+commands in that it takes up to two line numbers in front
+that tell what lines are to be affected.
+It is also
+.ul
+followed
+by a line number that tells where the lines are to go.
+Thus
+.P1
+line1, line2 m line3
+.P2
+says to move all the lines between
+`line1'
+and
+`line2'
+after
+`line3'.
+Naturally, any of
+`line1'
+etc., can be patterns between slashes,
+$
+signs, or other ways to specify lines.
+.PP
+Suppose again that you're sitting at the first line of the
+paragraph.
+Then you can say
+.P1
+\&\*.,/^\*e\*.PP/-m$
+.P2
+That's all.
+.PP
+As another example of a frequent operation,
+you can reverse the order of two adjacent lines
+by moving the first one
+to after the second.
+Suppose that you are positioned at the first.
+Then
+.P1
+m+
+.P2
+does it.
+It says to move line dot to after one line after line dot.
+.PP
+As you can see, the
+.UL m
+command is more succinct and direct than
+writing, deleting and re-reading.
+When is brute force better anyway?
+This is a matter of personal taste _
+do what you have most confidence in.
+The main difficulty with the
+.UL m
+command
+is that if you use patterns to specify both the lines
+you are moving and the target,
+you have to take care that you specify them properly,
+or you may well not move the lines you thought you did.
+The result of a botched
+.UL m
+command can be a ghastly mess.
+Doing the job a step at a time
+makes it easier for you to verify at each step
+that you accomplished what you wanted to.
+It's also a good idea to issue a
+.UL w
+command
+before doing anything complicated;
+then if you goof, it's easy to back up
+to where you were.
+.SH
+Marks
+.PP
+.UL ed
+provides a facility for marking a line
+with a particular name so you can later reference it
+by name
+regardless of its actual line number.
+This can be handy for moving lines,
+and for keeping track of them even after they've been moved.
+The
+.ul
+mark
+command is
+.UL k ;
+the command
+.P1
+kx
+.P2
+marks the current line with the name `x'.
+If a line number precedes the
+.UL k ,
+that line is marked.
+(The mark name must be a single lower case letter.)
+Now you can refer to the marked line with the address
+.P1
+\(fmx
+.P2
+.PP
+Marks are most useful for moving things around.
+Find the first line of the block to be moved, and mark it
+with
+.UL ka .
+Then find the last line and mark it with
+.UL kb .
+Now position yourself at the place where the stuff is to go
+and say
+.P1
+\(fma,\(fmbm\*.
+.P2
+.PP
+Bear in mind that only one line can have a particular
+mark name associated with it
+at any given time.
+.SH
+Copying Lines
+.PP
+We mentioned earlier the idea of saving a line
+that was hard to type or used often,
+so as to cut down on typing time.
+Of course this could be more than one line;
+then the saving is presumably even greater.
+.PP
+.UL ed
+provides another command,
+called
+.UL t
+(for `transfer')
+for making a copy of a group of one or more lines
+at any point.
+This is often easier than writing and reading.
+.PP
+The
+.UL t
+command is identical to the
+.UL m
+command, except that instead of moving lines
+it simply duplicates them at the place you named.
+Thus
+.P1
+1,$t$
+.P2
+duplicates the entire contents that you are editing.
+A more common use for
+.UL t
+is for creating a series of lines that differ only slightly.
+For example, you can say
+.P1
+.ta 1i
+a
+\&.......... x ......... (long line)
+\&\*.
+t\*. (make a copy)
+s/x/y/ (change it a bit)
+t\*. (make third copy)
+s/y/z/ (change it a bit)
+.P2
+and so on.
+.SH
+The Temporary Escape `!'
+.PP
+Sometimes it is convenient to be able
+to temporarily escape from the editor to do
+some other
+.UX
+command,
+perhaps one of the file copy or move commands
+discussed in section 5,
+without leaving the editor.
+The `escape' command
+.UL !
+provides a way to do this.
+.PP
+If you say
+.P1
+!any UNIX command
+.P2
+your current editing state is suspended,
+and the
+.UX
+command you asked for is executed.
+When the command finishes,
+.UL ed
+will signal you by printing another
+.UL ! ;
+at that point you can resume editing.
+.PP
+You can really do
+.ul
+any
+.UX
+command, including another
+.UL ed .
+(This is quite common, in fact.)
+In this case, you can even do another
+.UL ! .
+.PP
+On Berkeley
+.UX
+systems, there is an additional (and preferable) mechanism called
+.ul
+job control
+which lets you suspend your edit session (or, for that matter,
+any program), return to the shell from
+which you invoked that program, and issue any commands, then resume
+the program from the point where it was stopped. See
+.ul
+An Introduction to the C Shell
+for more details.
diff --git a/bin/ed/USD.doc/10.edadv/ae7 b/bin/ed/USD.doc/10.edadv/ae7
new file mode 100644
index 0000000..8473fb0
--- /dev/null
+++ b/bin/ed/USD.doc/10.edadv/ae7
@@ -0,0 +1,219 @@
+.\" $OpenBSD: ae7,v 1.3 2004/04/06 08:19:20 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)ae7 8.1 (Berkeley) 6/8/93
+.\"
+.NH
+SUPPORTING TOOLS
+.PP
+There are several tools and techniques that go along with the
+editor, all of which are relatively easy once you
+know how
+.UL ed
+works,
+because they are all based on the editor.
+In this section we will give some fairly cursory examples
+of these tools,
+more to indicate their existence than to provide
+a complete tutorial.
+More information on each can be found in
+[3].
+.SH
+Grep
+.PP
+Sometimes you want to find all occurrences of some word or pattern in
+a set of files, to edit them
+or perhaps just to verify their presence or absence.
+It may be possible to edit each file separately and look
+for the pattern of interest, but if there are many files
+this can get very tedious,
+and if the files are really big,
+it may be impossible because of limits in
+.UL ed .
+.PP
+The program
+.UL grep
+was invented to get around these limitations.
+The search patterns that we have described in the paper are often
+called `regular expressions', and
+`grep' stands for
+.P1
+g/re/p
+.P2
+That describes exactly what
+.UL grep
+does _
+it prints every line in a set of files that contains a
+particular pattern.
+Thus
+.P1
+grep \(fmthing\(fm file1 file2 file3 ...
+.P2
+finds `thing' wherever it occurs in any of the files
+`file1',
+`file2',
+etc.
+.UL grep
+also indicates the file in which the line was found,
+so you can later edit it if you like.
+.PP
+The pattern represented by `thing' can be any
+pattern you can use in the editor,
+since
+.UL grep
+and
+.UL ed
+use exactly the same mechanism for
+pattern searching.
+It is wisest always to enclose the pattern in the
+single quotes \(fm...\(fm if it contains any non-alphabetic
+characters, since many such characters also mean something
+special to the
+.UX
+command interpreter
+(the `shell').
+If you don't quote them, the command interpreter will
+try to interpret them before
+.UL grep
+gets a chance.
+.PP
+There is also a way to find lines that
+.ul
+don't
+contain a pattern:
+.P1
+grep -v \(fmthing\(fm file1 file2 ...
+.P2
+finds all lines that
+don't contains `thing'.
+The
+.UL \-v
+must occur in the position shown.
+Given
+.UL grep
+and
+.UL grep\ \-v ,
+it is possible to do things like selecting all lines that
+contain some combination of patterns.
+For example, to get all lines that contain `x' but not `y':
+.P1
+grep x file... | grep -v y
+.P2
+(The notation | is a `pipe',
+which causes the output of the first command to be used as
+input to the second command; see [2].)
+.SH
+Editing Scripts
+.PP
+If a fairly complicated set of editing operations
+is to be done on a whole set of files,
+the easiest thing to do is to make up a `script',
+i.e., a file that contains the operations you want to perform,
+then apply this script to each file in turn.
+.PP
+For example, suppose you want to change every
+`Unix' to `UNIX' and every `Gcos' to `GCOS' in a large number of files.
+Then put into the file `script' the lines
+.P1
+g/Unix/s//UNIX/g
+g/Gcos/s//GCOS/g
+w
+q
+.P2
+Now you can say
+.P1
+ed file1 <script
+ed file2 <script
+\&...
+.P2
+This causes
+.UL ed
+to take its commands from the prepared script.
+Notice that the whole job has to be planned in advance.
+.PP
+And of course by using the
+.UX
+command interpreter, you can
+cycle through a set of files
+automatically, with varying degrees of ease.
+.SH
+Sed
+.PP
+.UL sed
+(`stream editor')
+is a version of the editor with restricted capabilities
+but which is capable of processing unlimited amounts of input.
+Basically
+.UL sed
+copies its input to its output, applying one or more
+editing commands to each line of input.
+.PP
+As an example, suppose that we want to do the `Unix' to `UNIX'
+part of the
+example given above,
+but without rewriting the files.
+Then the command
+.P1
+sed \(fms/Unix/UNIX/g\(fm file1 file2 ...
+.P2
+applies the command
+`s/Unix/UNIX/g'
+to all lines from `file1', `file2', etc.,
+and copies all lines to the output.
+The advantage of using
+.UL sed
+in such a case is that it can be used
+with input too large for
+.UL ed
+to handle.
+All the output can be collected in one place,
+either in a file or perhaps piped into another program.
+.PP
+If the editing transformation is so complicated
+that
+more than one editing command is needed,
+commands can be supplied from a file,
+or on the command line,
+with a slightly more complex syntax.
+To take commands from a file, for example,
+.P1
+sed -f cmdfile input-files...
+.P2
+.PP
+.UL sed
+has further capabilities, including conditional testing
+and branching, which we cannot go into here, but which are
+described in detail in
+.UL "Sed \- A Non-interactive Text Editor" .
+
diff --git a/bin/ed/USD.doc/10.edadv/ae9 b/bin/ed/USD.doc/10.edadv/ae9
new file mode 100644
index 0000000..226675f
--- /dev/null
+++ b/bin/ed/USD.doc/10.edadv/ae9
@@ -0,0 +1,55 @@
+.\" $OpenBSD: ae9,v 1.3 2004/04/06 08:19:20 jmc Exp $
+.\"
+.\" 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:
+.\" 1. Redistributions of source code and documentation 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 or owned by Caldera
+.\" International, Inc.
+.\" 4. 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.
+.\"
+.\" @(#)ae9 8.1 (Berkeley) 6/8/93
+.\"
+.SH
+Acknowledgement
+.PP
+I am grateful to Ted Dolotta
+for his careful reading and valuable suggestions.
+.SH
+References
+.IP [1]
+Brian W. Kernighan,
+.UL "A Tutorial Introduction to the UNIX Text Editor" ,
+Bell Laboratories internal memorandum.
+.IP [2]
+Brian W. Kernighan,
+.UL "UNIX For Beginners" ,
+Bell Laboratories internal memorandum.
+.IP [3]
+Ken L. Thompson and Dennis M. Ritchie,
+.UL "The UNIX Programmer's Manual" .
+Bell Laboratories.
diff --git a/bin/ed/buf.c b/bin/ed/buf.c
new file mode 100644
index 0000000..14987cf
--- /dev/null
+++ b/bin/ed/buf.c
@@ -0,0 +1,290 @@
+/* $OpenBSD: buf.c,v 1.23 2016/03/22 17:58:28 mmcc Exp $ */
+/* $NetBSD: buf.c,v 1.15 1995/04/23 10:07:28 cgd Exp $ */
+
+/* buf.c: This file contains the scratch-file buffer routines for the
+ ed line editor. */
+/*-
+ * Copyright (c) 1993 Andrew Moore, Talke Studio.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <limits.h>
+#include <regex.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "ed.h"
+
+
+static FILE *sfp; /* scratch file pointer */
+static off_t sfseek; /* scratch file position */
+static int seek_write; /* seek before writing */
+static line_t buffer_head; /* incore buffer */
+
+/* get_sbuf_line: get a line of text from the scratch file; return pointer
+ to the text */
+char *
+get_sbuf_line(line_t *lp)
+{
+ static char *sfbuf = NULL; /* buffer */
+ static int sfbufsz = 0; /* buffer size */
+
+ int len, ct;
+
+ if (lp == &buffer_head)
+ return NULL;
+ seek_write = 1; /* force seek on write */
+ /* out of position */
+ if (sfseek != lp->seek) {
+ sfseek = lp->seek;
+ if (fseeko(sfp, sfseek, SEEK_SET) < 0) {
+ perror(NULL);
+ seterrmsg("cannot seek temp file");
+ return NULL;
+ }
+ }
+ len = lp->len;
+ REALLOC(sfbuf, sfbufsz, len + 1, NULL);
+ if ((ct = fread(sfbuf, sizeof(char), len, sfp)) < 0 || ct != len) {
+ perror(NULL);
+ seterrmsg("cannot read temp file");
+ return NULL;
+ }
+ sfseek += len; /* update file position */
+ sfbuf[len] = '\0';
+ return sfbuf;
+}
+
+
+/* put_sbuf_line: write a line of text to the scratch file and add a line node
+ to the editor buffer; return a pointer to the end of the text */
+char *
+put_sbuf_line(char *cs)
+{
+ line_t *lp;
+ int len, ct;
+ char *s;
+
+ if ((lp = malloc(sizeof(line_t))) == NULL) {
+ perror(NULL);
+ seterrmsg("out of memory");
+ return NULL;
+ }
+ /* assert: cs is '\n' terminated */
+ for (s = cs; *s != '\n'; s++)
+ ;
+ if (s - cs >= LINECHARS) {
+ seterrmsg("line too long");
+ free(lp);
+ return NULL;
+ }
+ len = s - cs;
+ /* out of position */
+ if (seek_write) {
+ if (fseek(sfp, 0L, SEEK_END) < 0) {
+ perror(NULL);
+ seterrmsg("cannot seek temp file");
+ free(lp);
+ return NULL;
+ }
+ sfseek = ftello(sfp);
+ seek_write = 0;
+ }
+ /* assert: SPL1() */
+ if ((ct = fwrite(cs, sizeof(char), len, sfp)) < 0 || ct != len) {
+ sfseek = -1;
+ perror(NULL);
+ seterrmsg("cannot write temp file");
+ free(lp);
+ return NULL;
+ }
+ lp->len = len;
+ lp->seek = sfseek;
+ add_line_node(lp);
+ sfseek += len; /* update file position */
+ return ++s;
+}
+
+
+/* add_line_node: add a line node in the editor buffer after the current line */
+void
+add_line_node(line_t *lp)
+{
+ line_t *cp;
+
+ /* this get_addressed_line_node last! */
+ cp = get_addressed_line_node(current_addr);
+ INSQUE(lp, cp);
+ addr_last++;
+ current_addr++;
+}
+
+
+/* get_line_node_addr: return line number of pointer */
+int
+get_line_node_addr(line_t *lp)
+{
+ line_t *cp = &buffer_head;
+ int n = 0;
+
+ while (cp != lp && (cp = cp->q_forw) != &buffer_head)
+ n++;
+ if (n && cp == &buffer_head) {
+ seterrmsg("invalid address");
+ return ERR;
+ }
+ return n;
+}
+
+
+/* get_addressed_line_node: return pointer to a line node in the editor buffer */
+line_t *
+get_addressed_line_node(int n)
+{
+ static line_t *lp = &buffer_head;
+ static int on = 0;
+
+ SPL1();
+ if (n > on) {
+ if (n <= (on + addr_last) >> 1)
+ for (; on < n; on++)
+ lp = lp->q_forw;
+ else {
+ lp = buffer_head.q_back;
+ for (on = addr_last; on > n; on--)
+ lp = lp->q_back;
+ }
+ } else {
+ if (n >= on >> 1)
+ for (; on > n; on--)
+ lp = lp->q_back;
+ else {
+ lp = &buffer_head;
+ for (on = 0; on < n; on++)
+ lp = lp->q_forw;
+ }
+ }
+ SPL0();
+ return lp;
+}
+
+
+extern int newline_added;
+
+#define SCRATCH_TEMPLATE "/tmp/ed.XXXXXXXXXX"
+static char sfn[sizeof(SCRATCH_TEMPLATE)+1] = ""; /* scratch file name */
+
+/* open_sbuf: open scratch file */
+int
+open_sbuf(void)
+{
+ int fd = -1;
+
+ isbinary = newline_added = 0;
+ strlcpy(sfn, SCRATCH_TEMPLATE, sizeof sfn);
+ if ((fd = mkstemp(sfn)) == -1 ||
+ (sfp = fdopen(fd, "w+")) == NULL) {
+ if (fd != -1)
+ close(fd);
+ perror(sfn);
+ seterrmsg("cannot open temp file");
+ return ERR;
+ }
+ return 0;
+}
+
+
+/* close_sbuf: close scratch file */
+int
+close_sbuf(void)
+{
+ if (sfp) {
+ if (fclose(sfp) < 0) {
+ perror(sfn);
+ seterrmsg("cannot close temp file");
+ return ERR;
+ }
+ sfp = NULL;
+ unlink(sfn);
+ }
+ sfseek = seek_write = 0;
+ return 0;
+}
+
+
+/* quit: remove_lines scratch file and exit */
+void
+quit(int n)
+{
+ if (sfp) {
+ fclose(sfp);
+ unlink(sfn);
+ }
+ exit(n);
+}
+
+
+static unsigned char ctab[256]; /* character translation table */
+
+/* init_buffers: open scratch buffer; initialize line queue */
+void
+init_buffers(void)
+{
+ int i = 0;
+
+ /* Read stdin one character at a time to avoid i/o contention
+ with shell escapes invoked by nonterminal input, e.g.,
+ ed - <<EOF
+ !cat
+ hello, world
+ EOF */
+ setvbuf(stdin, NULL, _IONBF, 0);
+ if (open_sbuf() < 0)
+ quit(2);
+ REQUE(&buffer_head, &buffer_head);
+ for (i = 0; i < 256; i++)
+ ctab[i] = i;
+}
+
+
+/* translit_text: translate characters in a string */
+char *
+translit_text(char *s, int len, int from, int to)
+{
+ static int i = 0;
+
+ unsigned char *us;
+
+ ctab[i] = i; /* restore table to initial state */
+ ctab[i = from] = to;
+ for (us = (unsigned char *) s; len-- > 0; us++)
+ *us = ctab[*us];
+ return s;
+}
diff --git a/bin/ed/ed.1 b/bin/ed/ed.1
new file mode 100644
index 0000000..dbf7f55
--- /dev/null
+++ b/bin/ed/ed.1
@@ -0,0 +1,851 @@
+.\" $OpenBSD: ed.1,v 1.67 2015/11/20 20:13:32 tb Exp $
+.\"
+.\" Copyright (c) 1993 Andrew Moore, Talke Studio.
+.\" 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.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+.\"
+.Dd $Mdocdate: November 20 2015 $
+.Dt ED 1
+.Os
+.Sh NAME
+.Nm ed
+.Nd text editor
+.Sh SYNOPSIS
+.Nm ed
+.Op Fl
+.Op Fl s
+.Op Fl p Ar string
+.Op Ar file
+.Sh DESCRIPTION
+.Nm
+is a line-oriented text editor.
+It is used to create, display, modify, and otherwise manipulate text files.
+If invoked with a
+.Ar file
+argument, then a copy of
+.Ar file
+is read into the editor's buffer.
+Changes are made to this copy and not directly to
+.Ar file
+itself.
+Upon quitting
+.Nm ed ,
+any changes not explicitly saved with a
+.Ic w
+command are lost.
+.Pp
+Editing is done in two distinct modes:
+.Em command
+and
+.Em input .
+When first invoked,
+.Nm
+is in command mode.
+In this mode, commands are read from the standard input and
+executed to manipulate the contents of the editor buffer.
+.Pp
+A typical command might look like:
+.Pp
+.Dl ,s/old/new/g
+.Pp
+which replaces all occurrences of the string
+.Qq old
+with
+.Qq new .
+.Pp
+When an input command, such as
+.Ic a
+.Pq append ,
+.Ic i
+.Pq insert ,
+or
+.Ic c
+.Pq change
+is given,
+.Nm
+enters input mode.
+This is the primary means of adding text to a file.
+In this mode, no commands are available;
+instead, the standard input is written directly to the editor buffer.
+Lines consist of text up to and including a newline character.
+Input mode is terminated by entering a single period
+.Pq Ql \&.
+on a line.
+.Pp
+All
+.Nm
+commands operate on whole lines or ranges of lines; e.g.,
+the
+.Ic d
+command deletes lines; the
+.Ic m
+command moves lines, and so on.
+It is possible to modify only a portion of a line by means of replacement,
+as in the example above.
+However, even here, the
+.Ic s
+command is applied to whole lines at a time.
+.Pp
+In general,
+.Nm
+commands consist of zero or more line addresses, followed by a single
+character command and possibly additional parameters; i.e.,
+commands have the structure:
+.Pp
+.Dl [address [,address]]command[parameters]
+.Pp
+The address(es) indicate the line or range of lines to be affected by the
+command.
+If fewer addresses are given than the command accepts, then
+default addresses are supplied.
+.Pp
+Many
+.Nm
+commands and line addresses support basic regular expressions
+.Pq BREs .
+See
+.Xr re_format 7
+for more information on regular expressions.
+.Pp
+The options are as follows:
+.Bl -tag -width "-p string"
+.It Fl
+Same as the
+.Fl s
+option
+.Pq deprecated .
+.It Fl p Ar string
+Specifies a command prompt.
+This may be toggled on and off with the
+.Ic P
+command.
+.It Fl s
+Suppress diagnostics.
+This should be used if
+.Nm
+standard input is from a script.
+.It Ar file
+Specifies the name of a file to read.
+If
+.Ar file
+is prefixed with a
+bang
+.Pq Ql \&! ,
+then it is interpreted as a shell command.
+In this case, what is read is the standard output of
+.Ar file
+executed via
+.Xr sh 1 .
+To read a file whose name begins with a bang, prefix the
+name with a backslash
+.Pq Ql \e .
+The default filename is set to
+.Ar file
+only if it is not prefixed with a bang.
+.El
+.Ss LINE ADDRESSING
+An address represents the number of a line in the buffer.
+.Nm
+maintains a
+.Em current address
+which is typically supplied to commands as the default address
+when none is specified.
+When a file is first read, the current address is set to the last line
+of the file.
+In general, the current address is set to the last line affected by a command.
+.Pp
+A line address is
+constructed from one of the bases in the list below, optionally followed
+by a numeric offset.
+The offset may include any combination of digits, operators (e.g.,
+.Ql + ,
+.Ql - ,
+and
+.Ql ^ ) ,
+and whitespace.
+Addresses are read from left to right, and their values are computed
+relative to the current address.
+.Pp
+One exception to the rule that addresses represent line numbers is the
+address
+.Ad 0
+.Pq zero .
+This means
+.Dq before the first line ,
+and is legal wherever it makes sense.
+.Pp
+An address range is two addresses separated either by a comma or semi-colon.
+The value of the first address in a range cannot exceed the
+value of the second.
+If only one address is given in a range,
+then the second address is set to the given address.
+If an
+.Ar n Ns -tuple
+of addresses is given where
+.Ar n
+\*(Gt 2,
+then the corresponding range is determined by the last two addresses in the
+.Ar n Ns -tuple .
+If only one address is expected, then the last address is used.
+.Pp
+Each address in a comma-delimited range is interpreted relative to the
+current address.
+In a semi-colon-delimited range, the first address is
+used to set the current address, and the second address is interpreted
+relative to the first.
+.Pp
+The following address symbols are recognized:
+.Bl -tag -width Ds
+.It \&.
+The current line
+.Pq address
+in the buffer.
+.It $
+The last line in the buffer.
+.It Ar n
+The
+.Ar n Ns th
+line in the buffer, where
+.Ar n
+is a number in the range
+.Ad [0,$] .
+.It - or ^
+The previous line.
+This is equivalent to
+.Ad \-1
+and may be repeated with cumulative effect.
+.It Xo
+.Pf - Ar n No or\ \&
+.Pf ^ Ar n
+.Xc
+The
+.Ar n Ns th
+previous line, where
+.Ar n
+is a non-negative number.
+.It +
+The next line.
+This is equivalent to
+.Ad +1
+and may be repeated with cumulative effect.
+.It + Ns Ar n
+The
+.Ar n Ns th
+next line, where
+.Ar n
+is a non-negative number.
+.It \&, or %
+The first through last lines in the buffer.
+This is equivalent to the address range
+.Ad 1,$ .
+.It \&;
+The current through last lines in the buffer.
+This is equivalent to the address range
+.Ad .,$ .
+.It / Ns Ar re Ns /
+The next line containing the regular expression
+.Ar re .
+The search wraps to the beginning of the buffer and continues down to the
+current line, if necessary.
+.Qq //
+repeats the last search.
+.It ? Ns Ar re Ns ?
+The previous line containing the regular expression
+.Ar re .
+The search wraps to the end of the buffer and continues up to the
+current line, if necessary.
+.Qq ??
+repeats the last search.
+.It \&' Ns Ar lc
+The line previously marked by a
+.Ic k
+.Pq mark
+command, where
+.Ar lc
+is a lower case letter.
+.El
+.Ss COMMANDS
+All
+.Nm
+commands are single characters, though some require additional parameters.
+If a command's parameters extend over several lines, then
+each line except for the last must be terminated with a backslash
+.Pq Ql \e .
+.Pp
+In general, at most one command is allowed per line.
+However, most commands accept a print suffix, which is any of
+.Ic p
+.Pq print ,
+.Ic l
+.Pq list ,
+or
+.Ic n
+.Pq enumerate ,
+to print the last line affected by the command.
+.Pp
+.Nm
+recognizes the following commands.
+The commands are shown together with
+the default address or address range supplied if none is specified
+.Pq in parentheses ,
+and other possible arguments on the right.
+.Bl -tag -width Dxxs
+.It (.) Ns Ic a
+Appends text to the buffer after the addressed line.
+Text is entered in input mode.
+The current address is set to last line entered.
+.It (.,.) Ns Ic c
+Changes lines in the buffer.
+The addressed lines are deleted from the buffer,
+and text is appended in their place.
+Text is entered in input mode.
+The current address is set to last line entered.
+.It (.,.) Ns Ic d
+Deletes the addressed lines from the buffer.
+If there is a line after the deleted range, then the current address is set
+to this line.
+Otherwise the current address is set to the line before the deleted range.
+.It Ic e Ar file
+Edits
+.Ar file ,
+and sets the default filename.
+If
+.Ar file
+is not specified, then the default filename is used.
+Any lines in the buffer are deleted before the new file is read.
+The current address is set to the last line read.
+.It Ic e No \&! Ns Ar command
+Edits the standard output of
+.No \&! Ns Ar command ,
+(see
+.Ic \&! Ns Ar command
+below).
+The default filename is unchanged.
+Any lines in the buffer are deleted before the output of
+.Ar command
+is read.
+The current address is set to the last line read.
+.It Ic E Ar file
+Edits
+.Ar file
+unconditionally.
+This is similar to the
+.Ic e
+command, except that unwritten changes are discarded without warning.
+The current address is set to the last line read.
+.It Ic f Ar file
+Sets the default filename to
+.Ar file .
+If
+.Ar file
+is not specified, then the default unescaped filename is printed.
+.Sm off
+.It Xo
+.Pf (1,$) Ic g No /
+.Ar re No / Ar command-list
+.Xc
+.Sm on
+Applies
+.Ar command-list
+to each of the addressed lines matching a regular expression
+.Ar re .
+The current address is set to the line currently matched before
+command-list is executed.
+At the end of the
+.Ic g
+command, the current address is set to the last line affected by command-list.
+If no lines were matched,
+the current line number remains unchanged.
+.Pp
+Each command in
+.Ar command-list
+must be on a separate line,
+and every line except for the last must be terminated by a backslash
+.Pq Sq \e .
+Any commands are allowed, except for
+.Ic g ,
+.Ic G ,
+.Ic v ,
+and
+.Ic V .
+A newline alone in command-list is equivalent to a
+.Ic p
+command.
+.Sm off
+.It (1,$) Ic G No / Ar re No /
+.Sm on
+Interactively edits the addressed lines matching a regular expression
+.Ar re .
+For each matching line, the line is printed, the current address is set,
+and the user is prompted to enter a
+.Ar command-list .
+At the end of the
+.Ic G
+command, the current address is set to the last line affected by
+.Pq the last
+command-list.
+If no lines were matched,
+the current line number remains unchanged.
+.Pp
+The format of
+.Ar command-list
+is the same as that of the
+.Ic g
+command.
+A newline alone acts as a null command list.
+A single
+.Sq &
+repeats the last non-null command list.
+.It Ic H
+Toggles the printing of error explanations.
+By default, explanations are not printed.
+It is recommended that
+.Nm
+scripts begin with this command to aid in debugging.
+.It Ic h
+Prints an explanation of the last error.
+.It (.) Ns Ic i
+Inserts text in the buffer before the current line.
+Text is entered in input mode.
+The current address is set to the last line entered.
+.It (.,.+1) Ns Ic j
+Joins the addressed lines.
+The addressed lines are deleted from the buffer and replaced by a single
+line containing their joined text.
+The current address is set to the resultant line.
+.It (.) Ns Ic k Ns Ar lc
+Marks a line with a lower case letter
+.Ar lc .
+The line can then be addressed as
+.Ic ' Ns Ar lc
+(i.e., a single quote followed by
+.Ar lc )
+in subsequent commands.
+The mark is not cleared until the line is deleted or otherwise modified.
+.It (.,.) Ns Ic l
+Prints the addressed lines unambiguously.
+If a single line fills more than one screen (as might be the case
+when viewing a binary file, for instance), a
+.Dq --More--
+prompt is printed on the last line.
+.Nm
+waits until the RETURN key is pressed before displaying the next screen.
+The current address is set to the last line printed.
+.It (.,.) Ns Ic m Ns (.)
+Moves lines in the buffer.
+The addressed lines are moved to after the
+right-hand destination address, which may be the address
+.Ad 0
+.Pq zero .
+The current address is set to the last line moved.
+.It (.,.) Ns Ic n
+Prints the addressed lines along with their line numbers.
+The current address is set to the last line printed.
+.It (.,.) Ns Ic p
+Prints the addressed lines.
+The current address is set to the last line printed.
+.It Ic P
+Toggles the command prompt on and off.
+Unless a prompt was specified with the command-line option
+.Fl p Ar string ,
+the command prompt is by default turned off.
+.It Ic q
+Quits
+.Nm ed .
+.It Ic Q
+Quits
+.Nm
+unconditionally.
+This is similar to the
+.Ic q
+command, except that unwritten changes are discarded without warning.
+.It ($) Ns Ic r Ar file
+Reads
+.Ar file
+to after the addressed line.
+If
+.Ar file
+is not specified, then the default filename is used.
+If there was no default filename prior to the command,
+then the default filename is set to
+.Ar file .
+Otherwise, the default filename is unchanged.
+The current address is set to the last line read.
+.It ($) Ns Ic r No \&! Ns Ar command
+Reads to after the addressed line the standard output of
+.No \&! Ns Ar command ,
+(see
+.Ic \&! Ns Ar command
+below).
+The default filename is unchanged.
+The current address is set to the last line read.
+.Sm off
+.It Xo
+.Pf (.,.) Ic s No / Ar re
+.No / Ar replacement No /\ \&
+.Pf (.,.) Ic s No / Ar re
+.No / Ar replacement No / Ic g\ \&
+.No (.,.) Ic s No / Ar re
+.No / Ar replacement No / Ar n
+.Xc
+.Sm on
+Replaces text in the addressed lines matching a regular expression
+.Ar re
+with
+.Ar replacement .
+By default, only the first match in each line is replaced.
+If the
+.Ic g
+.Pq global
+suffix is given, then every match is replaced.
+The
+.Ar n
+suffix, where
+.Ar n
+is a positive number, causes only the
+.Ar n Ns th
+match to be replaced.
+It is an error if no substitutions are performed on any of the addressed
+lines.
+The current address is set the last line affected.
+.Pp
+.Ar re
+and
+.Ar replacement
+may be delimited by any character other than space and newline
+(see the
+.Ic s
+command below).
+If one or two of the last delimiters is omitted, then the last line
+affected is printed as though the print suffix
+.Ic p
+were specified.
+.Pp
+An unescaped
+.Ql &
+in
+.Ar replacement
+is replaced by the currently matched text.
+The character sequence
+.Pf \e Ar m ,
+where
+.Ar m
+is a number in the range [1,9], is replaced by the
+.Ar m Ns th
+backreference expression of the matched text.
+If
+.Ar replacement
+consists of a single
+.Ql % ,
+then
+.Ar replacement
+from the last substitution is used.
+Newlines may be embedded in
+.Ar replacement
+if they are escaped with a backslash
+.Pq Ql \e .
+.It (.,.) Ns Ic s
+Repeats the last substitution.
+This form of the
+.Ic s
+command accepts a count suffix
+.Ar n ,
+or any combination of the characters
+.Ic r ,
+.Ic g ,
+and
+.Ic p .
+If a count suffix
+.Ar n
+is given, then only the
+.Ar n Ns th
+match is replaced.
+The
+.Ic r
+suffix causes the regular expression of the last search to be used
+instead of that of the last substitution.
+The
+.Ic g
+suffix toggles the global suffix of the last substitution.
+The
+.Ic p
+suffix toggles the print suffix of the last substitution.
+The current address is set to the last line affected.
+.It (.,.) Ns Ic t Ns (.)
+Copies
+.Pq i.e., transfers
+the addressed lines to after the right-hand destination address,
+which may be the address
+.Ad 0
+.Pq zero .
+The current address is set to the last line copied.
+.It Ic u
+Undoes the last command and restores the current address
+to what it was before the command.
+The global commands
+.Ic g ,
+.Ic G ,
+.Ic v ,
+and
+.Ic V
+are treated as a single command by undo.
+.Ic u
+is its own inverse.
+.Sm off
+.It Xo
+.Pf (1,$) Ic v No / Ar re
+.Pf / Ar command-list
+.Xc
+.Sm on
+Applies
+.Ar command-list
+to each of the addressed lines not matching a regular expression
+.Ar re .
+This is similar to the
+.Ic g
+command.
+.Sm off
+.It Xo
+.Pf (1,$) Ic V No /
+.Ar re No /
+.Xc
+.Sm on
+Interactively edits the addressed lines not matching a regular expression
+.Ar re .
+This is similar to the
+.Ic G
+command.
+.It (1,$) Ns Ic w Ar file
+Writes the addressed lines to
+.Ar file .
+Any previous contents of
+.Ar file
+are lost without warning.
+If there is no default filename, then the default filename is set to
+.Ar file ,
+otherwise it is unchanged.
+If no filename is specified, then the default filename is used.
+The current address is unchanged.
+.It (1,$) Ns Ic wq Ar file
+Writes the addressed lines to
+.Ar file ,
+and then executes a
+.Ic q
+command.
+.It (1,$) Ns Ic w No \&! Ns Ar command
+Writes the addressed lines to the standard input of
+.No \&! Ns Ar command ,
+(see
+.Ic \&! Ns Ar command
+below).
+The default filename and current address are unchanged.
+.It (1,$) Ns Ic W Ar file
+Appends the addressed lines to the end of
+.Ar file .
+This is similar to the
+.Ic w
+command, except that the previous contents of file are not clobbered.
+The current address is unchanged.
+.It (.+1) Ns Ic z Ns Ar n
+Scrolls
+.Ar n
+lines at a time starting at addressed line.
+If
+.Ar n
+is not specified, then the current window size is used.
+The current address is set to the last line printed.
+.It ($) Ns Ic =
+Prints the line number of the addressed line.
+.It (.+1) Ns newline
+Prints the addressed line, and sets the current address to that line.
+.It Ic \&! Ns Ar command
+Executes
+.Ar command
+via
+.Xr sh 1 .
+If the first character of
+.Ar command
+is
+.Sq !\& ,
+then it is replaced by text of the previous
+.Ic \&! Ns Ar command .
+.Nm
+does not process
+.Ar command
+for
+.Sq \e
+.Pq backslash
+escapes.
+However, an unescaped
+.Sq %
+is replaced by the default filename.
+When the shell returns from execution, a
+.Sq \&!
+is printed to the standard output.
+The current line is unchanged.
+.El
+.Sh ASYNCHRONOUS EVENTS
+.Bl -tag -width "SIGWINCH"
+.It Dv SIGHUP
+If the current buffer has changed since it was last written,
+.Nm
+attempts to write the buffer to the file
+.Pa ed.hup .
+Nothing is written to the currently remembered file, and
+.Nm
+exits.
+.It Dv SIGINT
+When an interrupt occurs,
+.Nm
+prints
+.Sq ?\en
+and returns to command mode.
+If interrupted during text input,
+the text already input is written to the current buffer,
+as if text input had been normally terminated.
+.It Dv SIGQUIT
+This signal is ignored.
+.It Dv SIGWINCH
+The screen is resized.
+.El
+.Sh FILES
+.Bl -tag -width /tmp/ed.* -compact
+.It Pa /tmp/ed.*
+buffer file
+.It Pa ed.hup
+where
+.Nm
+attempts to write the buffer if the terminal hangs up
+.El
+.Sh EXIT STATUS
+.Ex -std ed
+.Sh DIAGNOSTICS
+When an error occurs,
+.Nm
+prints a
+.Sq \&?
+and either returns to command mode or exits if its input is from a script.
+An explanation of the last error can be printed with the
+.Ic h
+.Pq help
+command.
+.Pp
+Since the
+.Ic g
+.Pq global
+command masks any errors from failed searches and substitutions,
+it can be used to perform conditional operations in scripts; e.g.,
+.Pp
+.Dl g/old/s//new/
+.Pp
+replaces any occurrences of
+.Qq old
+with
+.Qq new .
+.Pp
+If the
+.Ic u
+.Pq undo
+command occurs in a global command list,
+then the command list is executed only once.
+.Pp
+If diagnostics are not disabled, attempting to quit
+.Nm
+or edit another file before writing a modified buffer results in an error.
+If the command is entered a second time, it succeeds,
+but any changes to the buffer are lost.
+.Sh SEE ALSO
+.Xr sed 1 ,
+.Xr sh 1 ,
+.Xr vi 1 ,
+.Xr re_format 7
+.Rs
+.%A B. W. Kernighan
+.%A P. J. Plauger
+.%B Software Tools in Pascal
+.%O Addison-Wesley
+.%D 1981
+.Re
+.Sh STANDARDS
+The
+.Nm
+utility is compliant with the
+.St -p1003.1-2008
+specification.
+.Pp
+The commands
+.Cm s
+(to repeat the last substitution),
+.Cm W ,
+.Cm wq ,
+and
+.Cm z
+as well as the address specifier
+.Sq %
+are extensions to that specification.
+.Pp
+The
+.St -p1003.1-2008
+specification says the
+.Sq ^
+address specifier is neither required nor prohibited;
+additionally, it says behaviour for the
+.Fl
+option is
+.Dq unspecified .
+.Pp
+The
+.St -p1003.1-2008
+specification says the
+.Ic l
+command should mark the ends of lines with a
+.Sq $
+character,
+and that
+.Sq $
+characters
+within the text should be output preceded by a backslash;
+this implementation does not support that.
+.Sh HISTORY
+An
+.Nm
+command appeared in
+.At v1 .
+.Sh CAVEATS
+.Nm
+processes
+.Ar file
+arguments for backslash escapes, i.e., in a filename,
+any characters preceded by a backslash
+.Pq Ql \e
+are interpreted literally.
+.Pp
+If a text
+.Pq non-binary
+file is not terminated by a newline character,
+then
+.Nm
+appends one on reading/writing it.
+In the case of a binary file,
+.Nm
+does not append a newline on reading/writing.
diff --git a/bin/ed/ed.h b/bin/ed/ed.h
new file mode 100644
index 0000000..12d7e3d
--- /dev/null
+++ b/bin/ed/ed.h
@@ -0,0 +1,201 @@
+/* $OpenBSD: ed.h,v 1.22 2016/03/27 00:43:38 mmcc Exp $ */
+/* $NetBSD: ed.h,v 1.23 1995/03/21 09:04:40 cgd Exp $ */
+
+/* ed.h: type and constant definitions for the ed editor. */
+/*
+ * Copyright (c) 1993 Andrew Moore
+ * 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.
+ *
+ * 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.
+ *
+ * @(#)ed.h,v 1.5 1994/02/01 00:34:39 alm Exp
+ */
+
+#include <limits.h>
+#include <regex.h>
+#include <signal.h>
+
+#define ERR (-2)
+#define EMOD (-3)
+#define FATAL (-4)
+
+#define MINBUFSZ 512 /* minimum buffer size - must be > 0 */
+#define SE_MAX 30 /* max subexpressions in a regular expression */
+#define LINECHARS INT_MAX /* max chars per line */
+
+/* gflags */
+#define GLB 001 /* global command */
+#define GPR 002 /* print after command */
+#define GLS 004 /* list after command */
+#define GNP 010 /* enumerate after command */
+#define GSG 020 /* global substitute */
+
+/* Line node */
+typedef struct line {
+ struct line *q_forw;
+ struct line *q_back;
+ off_t seek; /* address of line in scratch buffer */
+ int len; /* length of line */
+} line_t;
+
+
+typedef struct undo {
+
+/* type of undo nodes */
+#define UADD 0
+#define UDEL 1
+#define UMOV 2
+#define VMOV 3
+
+ int type; /* command type */
+ line_t *h; /* head of list */
+ line_t *t; /* tail of list */
+} undo_t;
+
+#ifndef max
+# define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+#ifndef min
+# define min(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#define INC_MOD(l, k) ((l) + 1 > (k) ? 0 : (l) + 1)
+#define DEC_MOD(l, k) ((l) - 1 < 0 ? (k) : (l) - 1)
+
+/* SPL1: disable some interrupts (requires reliable signals) */
+#define SPL1() mutex++
+
+/* SPL0: enable all interrupts; check signal flags (requires reliable signals) */
+#define SPL0() \
+ do { \
+ if (--mutex == 0) { \
+ if (sighup) \
+ handle_hup(SIGHUP); \
+ if (sigint) \
+ handle_int(SIGINT); \
+ } \
+ } while (0)
+
+/* STRTOI: convert a string to int */
+#define STRTOI(i, p) { \
+ long l = strtol(p, &p, 10); \
+ if (l <= INT_MIN || l >= INT_MAX) { \
+ seterrmsg("number out of range"); \
+ i = 0; \
+ return ERR; \
+ } else \
+ i = (int)l; \
+}
+
+/* REALLOC: assure at least a minimum size for buffer b */
+#define REALLOC(b,n,i,err) \
+if ((i) > (n)) { \
+ int ti = (n); \
+ char *ts; \
+ SPL1(); \
+ if ((ts = realloc((b), ti += max((i), MINBUFSZ))) == NULL) { \
+ perror(NULL); \
+ seterrmsg("out of memory"); \
+ SPL0(); \
+ return err; \
+ } \
+ (n) = ti; \
+ (b) = ts; \
+ SPL0(); \
+}
+
+/* REQUE: link pred before succ */
+#define REQUE(pred, succ) (pred)->q_forw = (succ), (succ)->q_back = (pred)
+
+/* INSQUE: insert elem in circular queue after pred */
+#define INSQUE(elem, pred) \
+{ \
+ REQUE((elem), (pred)->q_forw); \
+ REQUE((pred), elem); \
+}
+
+/* remque: remove_lines elem from circular queue */
+#define REMQUE(elem) REQUE((elem)->q_back, (elem)->q_forw);
+
+/* NUL_TO_NEWLINE: overwrite ASCII NULs with newlines */
+#define NUL_TO_NEWLINE(s, l) translit_text(s, l, '\0', '\n')
+
+/* NEWLINE_TO_NUL: overwrite newlines with ASCII NULs */
+#define NEWLINE_TO_NUL(s, l) translit_text(s, l, '\n', '\0')
+
+/* Local Function Declarations */
+void add_line_node(line_t *);
+int build_active_list(int);
+void clear_active_list(void);
+void clear_undo_stack(void);
+int close_sbuf(void);
+int delete_lines(int, int);
+int display_lines(int, int, int);
+int exec_command(void);
+int exec_global(int, int);
+int extract_addr_range(void);
+int extract_subst_tail(int *, int *);
+line_t *get_addressed_line_node(int);
+regex_t *get_compiled_pattern(void);
+char *get_extended_line(int *, int);
+int get_line_node_addr(line_t *);
+char *get_sbuf_line(line_t *);
+int get_tty_line(void);
+void handle_hup(int);
+void handle_int(int);
+int has_trailing_escape(char *, char *);
+void init_buffers(void);
+int open_sbuf(void);
+int pop_undo_stack(void);
+undo_t *push_undo_stack(int, int, int);
+char *put_sbuf_line(char *);
+int put_tty_line(char *, int, int, int);
+void quit(int);
+int read_file(char *, int);
+int search_and_replace(regex_t *, int, int);
+void seterrmsg(char *);
+char *strip_escapes(char *);
+char *translit_text(char *, int, int, int);
+void unmark_line_node(line_t *);
+void unset_active_nodes(line_t *, line_t *);
+int write_file(char *, char *, int, int);
+
+/* global buffers */
+extern char *ibuf;
+extern char *ibufp;
+extern int ibufsz;
+
+/* global flags */
+extern int isbinary;
+extern int isglobal;
+extern int modified;
+
+extern volatile sig_atomic_t mutex;
+extern volatile sig_atomic_t sighup;
+extern volatile sig_atomic_t sigint;
+
+/* global vars */
+extern int addr_last;
+extern int current_addr;
+extern int first_addr;
+extern int lineno;
+extern int second_addr;
diff --git a/bin/ed/glbl.c b/bin/ed/glbl.c
new file mode 100644
index 0000000..b4cb41f
--- /dev/null
+++ b/bin/ed/glbl.c
@@ -0,0 +1,212 @@
+/* $OpenBSD: glbl.c,v 1.18 2016/03/22 17:58:28 mmcc Exp $ */
+/* $NetBSD: glbl.c,v 1.2 1995/03/21 09:04:41 cgd Exp $ */
+
+/* glob.c: This file contains the global command routines for the ed line
+ editor */
+/*-
+ * Copyright (c) 1993 Andrew Moore, Talke Studio.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ */
+
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+
+#include <regex.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ed.h"
+
+static int set_active_node(line_t *);
+static line_t *next_active_node(void);
+
+/* build_active_list: add line matching a pattern to the global-active list */
+int
+build_active_list(int isgcmd)
+{
+ regex_t *pat;
+ line_t *lp;
+ int n;
+ char *s;
+ char delimiter;
+
+ if ((delimiter = *ibufp) == ' ' || delimiter == '\n') {
+ seterrmsg("invalid pattern delimiter