Compare commits
378 Commits
v3.3.0
...
smp_might_
| Author | SHA1 | Date | |
|---|---|---|---|
| ef3427454e | |||
| b0eaaeda2b | |||
| b7d7e202a9 | |||
|
|
b7f0178aeb | ||
|
|
d1e4d7ce7d | ||
|
|
29346ab043 | ||
|
|
bc2d75fa05 | ||
|
|
0f8e20a12c | ||
|
|
cd27b2627a | ||
|
|
0f5c95a00b | ||
|
|
b80da2a01d | ||
| 81b1f87117 | |||
|
|
ba736c7968 | ||
|
|
7c48de6cc4 | ||
|
|
9488aa4c04 | ||
|
|
875abb8724 | ||
|
|
32b187558b | ||
|
|
d0055759dd | ||
|
|
fd962fdd93 | ||
|
|
c0d9ad695c | ||
|
|
33513d60e9 | ||
|
|
c175cce5e6 | ||
|
|
964427e0ea | ||
|
|
d8634bad6a | ||
|
|
040ec64444 | ||
|
|
319e7a6d07 | ||
|
|
e7ca52fbf9 | ||
|
|
93d36fc9d8 | ||
|
|
ed223591a8 | ||
|
|
20054ae93f | ||
|
|
26f5c8f84b | ||
|
|
d91f738bd8 | ||
|
|
594df55e53 | ||
|
|
e4d99eb9b0 | ||
|
|
fbbf2570b4 | ||
|
|
ef52a26bab | ||
|
|
f55e3cae08 | ||
|
|
65c4b82f02 | ||
|
|
5ba2e6e6e8 | ||
|
|
139ae0da30 | ||
|
|
0b98e8aad8 | ||
|
|
78ff1e69b6 | ||
|
|
0d6c408f48 | ||
|
|
728b0e5b34 | ||
|
|
129adfeb53 | ||
|
|
23369f9c9e | ||
|
|
3a3478dcea | ||
|
|
ebef68bf4c | ||
|
|
c8f6986185 | ||
|
|
1aad172900 | ||
|
|
a4220d7774 | ||
|
|
b6b6793d05 | ||
|
|
54434d4eff | ||
|
|
c0df94ec22 | ||
|
|
4506a0eebf | ||
|
|
7f79fb8810 | ||
|
|
5105ab554b | ||
|
|
c07c198b5f | ||
|
|
76b68f9f99 | ||
|
|
b7725c8552 | ||
|
|
9b9bea921f | ||
|
|
abf8a7e7b3 | ||
|
|
5a4672e300 | ||
|
|
40aba308a0 | ||
|
|
949a3e52e5 | ||
|
|
0acd3f1ae0 | ||
|
|
3e457fe321 | ||
|
|
b5e2faaaaf | ||
|
|
3956ee9eed | ||
|
|
63a89582ab | ||
| 44bb91d464 | |||
| 3ceafe99fd | |||
|
|
035cdb2e79 | ||
|
|
c9590fa23a | ||
| d8d3052dd0 | |||
|
|
f8ddf7c81d | ||
|
|
1e7bfb997f | ||
|
|
04c5ac3eb5 | ||
|
|
c3041d5c6d | ||
|
|
326b9df3db | ||
|
|
3779ed93c3 | ||
| 8b0f8559ee | |||
|
|
95cb93971a | ||
|
|
a6db4d0a62 | ||
|
|
8f4f859b35 | ||
|
|
2867e60add | ||
|
|
683f1fcab3 | ||
|
|
10e6ba68d2 | ||
|
|
8bab0dfa2a | ||
|
|
36f477c20e | ||
|
|
75206e2f3e | ||
| 0485087c58 | |||
|
|
0c474453d1 | ||
|
|
43065aa378 | ||
|
|
3f82ac6a4e | ||
|
|
dc76d7e9da | ||
|
|
3837bb5c0b | ||
|
|
eacaa8290b | ||
|
|
0be084004f | ||
|
|
37489f8a24 | ||
|
|
0e78c0166c | ||
|
|
2b641b28b1 | ||
|
|
50b7f13f9f | ||
|
|
5c8eb53d49 | ||
|
|
162b8995bb | ||
|
|
e3f3566e33 | ||
|
|
1aa4eb6a85 | ||
|
|
f16b761d2a | ||
|
|
fb6bd596bf | ||
|
|
d196e2c333 | ||
|
|
006d6e94f9 | ||
|
|
d40f735640 | ||
|
|
ac03aa4f32 | ||
|
|
e6f5b0cc65 | ||
|
|
dd09614042 | ||
|
|
65b4b95259 | ||
|
|
63483e02e6 | ||
|
|
53398d733f | ||
|
|
48f446ecd5 | ||
|
|
7f439d4656 | ||
|
|
704033fd9d | ||
|
|
d639cffec9 | ||
|
|
e1f889d228 | ||
|
|
01c875ce91 | ||
|
|
062400c0e2 | ||
|
|
56e56d2af2 | ||
|
|
9e6b1315c3 | ||
|
|
c8a9900b0c | ||
|
|
6fc5006250 | ||
|
|
a1760b573b | ||
|
|
76bf77a21f | ||
|
|
41022be182 | ||
|
|
606626c691 | ||
|
|
de95c84d3e | ||
|
|
fefec20e6b | ||
|
|
d09f72c453 | ||
|
|
1d9856e713 | ||
|
|
4b12166f26 | ||
|
|
29e004d23b | ||
|
|
56ac45c10b | ||
|
|
9f15e7b366 | ||
|
|
253dbfc285 | ||
|
|
6c31058de4 | ||
|
|
736b88cf53 | ||
|
|
4472b590c7 | ||
|
|
6c46a77d95 | ||
|
|
1311233cfb | ||
|
|
0314acfb2d | ||
|
|
b8f6d4a649 | ||
|
|
cb9453ca63 | ||
|
|
d75faf18d9 | ||
|
|
e94f856b38 | ||
|
|
b65ad59e08 | ||
|
|
bd851af48f | ||
|
|
162f54c289 | ||
|
|
e9cd054009 | ||
|
|
a6fc634735 | ||
|
|
ec725af4c5 | ||
|
|
efa7e3e6d2 | ||
|
|
a082b2af62 | ||
|
|
3091b8cf26 | ||
|
|
e10ce184e4 | ||
|
|
8731fd1c47 | ||
|
|
989398b447 | ||
|
|
ea69bfc71d | ||
|
|
1facb0487c | ||
|
|
7b2da7b2c7 | ||
|
|
e01448dd84 | ||
|
|
d8127f841f | ||
|
|
4796287659 | ||
|
|
3e07920fe2 | ||
|
|
818c405ae1 | ||
|
|
0184c63535 | ||
|
|
c97d4ff6e5 | ||
|
|
17fbdaf514 | ||
|
|
da32b6c32e | ||
|
|
424cad2cd6 | ||
|
|
6d315cbf9e | ||
|
|
65b4a7fa8d | ||
|
|
4a1befb81d | ||
|
|
85fb986ba7 | ||
|
|
86e41e22cf | ||
|
|
294d159017 | ||
|
|
3e8d796eaa | ||
|
|
3433559c50 | ||
|
|
c4182e08ab | ||
|
|
95b9ecf995 | ||
|
|
4d5b0de1fb | ||
|
|
35a4831d02 | ||
|
|
b329f2c73b | ||
| f837aff6e8 | |||
| 68afc7715b | |||
| 67b4718325 | |||
|
|
64d15bd98e | ||
|
|
c21aa858e2 | ||
|
|
5a7def9a94 | ||
|
|
a8f606defa | ||
|
|
f5321d8d55 | ||
|
|
0eabb93c0c | ||
|
|
da21d85025 | ||
|
|
0a2a08739e | ||
|
|
3f30eb69f0 | ||
|
|
22840dea11 | ||
|
|
07cbc27cb0 | ||
|
|
5055c7ea51 | ||
|
|
e1e2bc96d2 | ||
|
|
af4345b097 | ||
|
|
44707c1900 | ||
|
|
dfc3261535 | ||
|
|
7eb698ea4a | ||
|
|
179bddcf5d | ||
|
|
d9494baa34 | ||
|
|
c6748a4a93 | ||
|
|
c14bb31e67 | ||
|
|
be4841096d | ||
|
|
2a6b817353 | ||
|
|
c19d619d42 | ||
|
|
9cf6cc5098 | ||
|
|
f1489796fd | ||
|
|
eb95f895b2 | ||
|
|
3a1943c1c1 | ||
|
|
1cd28eb8e4 | ||
|
|
79444d163d | ||
|
|
93cdb3a735 | ||
|
|
e6df9032b3 | ||
|
|
f3734d6b31 | ||
|
|
e978660932 | ||
|
|
fc850d580c | ||
|
|
d1a87c1f64 | ||
|
|
d131b58784 | ||
|
|
6a0aa6fb5e | ||
|
|
0cf05b213d | ||
|
|
50d246bbba | ||
|
|
d82c151c9e | ||
|
|
31ba042920 | ||
|
|
80c94e3974 | ||
|
|
056ece2898 | ||
|
|
f113a7238f | ||
| 426224bbc6 | |||
|
|
6f55e9f11d | ||
|
|
271999a2f3 | ||
|
|
e3cf9c04f1 | ||
|
|
3bdcd28869 | ||
|
|
25223c2ae2 | ||
|
|
41b870c890 | ||
|
|
54841c0102 | ||
|
|
4f89addcc1 | ||
|
|
d91890d288 | ||
|
|
61890c3b2e | ||
|
|
e3b78ef14f | ||
|
|
1b6a97c9c0 | ||
|
|
dc0077241b | ||
|
|
7171c2321f | ||
|
|
b56a9d4725 | ||
| 3d0f2c86c4 | |||
|
|
f912036bae | ||
|
|
75e18fe498 | ||
|
|
3814aed560 | ||
|
|
2a3bc70264 | ||
|
|
3b0299dd65 | ||
|
|
29492bb71c | ||
|
|
f202792edf | ||
| 6c30d22a56 | |||
|
|
e1131d9c96 | ||
|
|
5ae1a533c7 | ||
| 41ba8c04cc | |||
|
|
ad8bffad67 | ||
|
|
5260f07c2c | ||
|
|
d76bd1f07c | ||
|
|
4081bff625 | ||
|
|
bcc1b08c61 | ||
|
|
6315775f16 | ||
|
|
5af3c2565f | ||
|
|
96e62d65b6 | ||
|
|
1ad10e3ae0 | ||
|
|
91c4db251e | ||
|
|
3913e49004 | ||
|
|
29018b4ecd | ||
|
|
b80fc5be89 | ||
|
|
dbcce9ddb0 | ||
|
|
107df7c8fa | ||
|
|
1539606d98 | ||
|
|
d1db724f47 | ||
|
|
a810336026 | ||
|
|
2e5374621d | ||
|
|
92293fafd3 | ||
|
|
4bf270019a | ||
|
|
cb796b7551 | ||
|
|
cc5b198875 | ||
|
|
3c8950cce9 | ||
|
|
7f59afadd5 | ||
| 0805ab8cfd | |||
|
|
99e9e03701 | ||
|
|
3a9e392b3a | ||
|
|
c9278f9170 | ||
|
|
65eccd1f74 | ||
| db1ca87b7d | |||
|
|
aa4ee93d43 | ||
|
|
b49f4cacde | ||
|
|
e321f65582 | ||
|
|
289b04677a | ||
|
|
31b6611abf | ||
|
|
f1abbce725 | ||
|
|
52be5c0afb | ||
|
|
5eefd0fec2 | ||
|
|
693ad767e8 | ||
|
|
f92baba71c | ||
|
|
7ee000e54a | ||
|
|
a8a812ef6a | ||
|
|
8b18d03deb | ||
|
|
92601f58cb | ||
|
|
f53651de01 | ||
| 957802cd0c | |||
| 123aceb045 | |||
| 86b0b2ca84 | |||
| 971bb1a587 | |||
| 1230fdc108 | |||
| 9e77ef5013 | |||
| 5d8311761a | |||
| 3641562f44 | |||
| 7eb99bda90 | |||
| 6e7bb62853 | |||
| 3d3105466a | |||
| 9393439a20 | |||
|
|
521fa314e2 | ||
|
|
10b559663e | ||
|
|
cb3a6387c8 | ||
|
|
1f945e8080 | ||
|
|
10b1b4ee12 | ||
|
|
e1c7263ee4 | ||
| ce3cb94487 | |||
|
|
eda6f5931d | ||
|
|
5d259c7f93 | ||
|
|
e985b92992 | ||
|
|
65f76edb8f | ||
|
|
5dd8da10c5 | ||
|
|
685aa79304 | ||
|
|
d794ecc9ef | ||
|
|
94e65446c4 | ||
|
|
1dcfbcd173 | ||
|
|
e5808135dd | ||
|
|
cbc8a0df90 | ||
|
|
e296281ce2 | ||
|
|
6990e61341 | ||
|
|
f4bd5678c6 | ||
|
|
f737eea636 | ||
|
|
347cc10a91 | ||
|
|
63ce03db66 | ||
|
|
e3fd605f72 | ||
|
|
5075cea916 | ||
|
|
0d9602e04b | ||
|
|
6a76678e59 | ||
|
|
ca78167b44 | ||
|
|
831337191b | ||
|
|
3a40bab785 | ||
|
|
ef9dc93f44 | ||
|
|
c2f99d7c3a | ||
|
|
edfcb02885 | ||
|
|
e2dc2c8954 | ||
|
|
3e08d38e8e | ||
|
|
1858c65d72 | ||
|
|
8ca6466a71 | ||
|
|
30d9b70391 | ||
|
|
f859061eaf | ||
|
|
2e89653e65 | ||
|
|
970d95ecd5 | ||
|
|
ccaeedb267 | ||
|
|
ad80a203db | ||
|
|
0dc5c83ec2 | ||
|
|
81db4f2cff | ||
|
|
a99c939dee | ||
|
|
ebd3c0673d | ||
|
|
c5beebb68d | ||
|
|
35118b0a91 | ||
|
|
f018897664 | ||
|
|
89c9de7d09 | ||
|
|
e7b4aa7d99 | ||
|
|
71cd1dd4b9 |
@@ -1,8 +1,8 @@
|
||||
# $NetBSD: Makefile,v 1.22 2007/12/31 15:31:24 ad Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
|
||||
SUBDIR= cat chmod cp date df echo ed expr hostname \
|
||||
kill ksh ln ls mkdir mv pax pwd rm rmdir sh \
|
||||
SUBDIR= cat chmod cp csh date dd df domainname echo ed expr hostname \
|
||||
kill ksh ln ls mkdir mv pax pwd rcp rcmd rm rmdir sh \
|
||||
sleep stty sync test
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
||||
76
bin/csh/Makefile
Normal file
76
bin/csh/Makefile
Normal file
@@ -0,0 +1,76 @@
|
||||
# $NetBSD: Makefile,v 1.39 2013/07/16 17:47:43 christos Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
#
|
||||
# C Shell with process control; VM/UNIX VAX Makefile
|
||||
# Bill Joy UC Berkeley; Jim Kulp IIASA, Austria
|
||||
#
|
||||
# To profile, put -DPROF in DFLAGS and -pg in COPTS, and recompile.
|
||||
|
||||
.include <bsd.own.mk>
|
||||
WARNS=6
|
||||
|
||||
PROG= csh
|
||||
DFLAGS=-DBUILTIN -DFILEC -DNLS -DSHORT_STRINGS
|
||||
# - Editor history not always aligned with shell history,
|
||||
# should implement internally
|
||||
# - Does not handle escaped prompts.
|
||||
# - Does not do completion
|
||||
.ifndef SMALLPROG
|
||||
DFLAGS+=-DEDIT
|
||||
.endif
|
||||
CPPFLAGS+=-I${.CURDIR} -I. ${DFLAGS}
|
||||
SRCS= alloc.c char.c const.c csh.c dir.c dol.c err.c exec.c exp.c file.c \
|
||||
func.c glob.c hist.c init.c lex.c misc.c parse.c printf.c proc.c \
|
||||
sem.c set.c str.c time.c
|
||||
.PATH: ${NETBSDSRCDIR}/usr.bin/printf
|
||||
|
||||
MLINKS= csh.1 limit.1 csh.1 alias.1 csh.1 bg.1 csh.1 dirs.1 csh.1 fg.1 \
|
||||
csh.1 foreach.1 csh.1 history.1 csh.1 jobs.1 csh.1 popd.1 \
|
||||
csh.1 pushd.1 csh.1 rehash.1 csh.1 repeat.1 csh.1 suspend.1 \
|
||||
csh.1 stop.1 csh.1 source.1
|
||||
|
||||
DPSRCS+= errnum.h const.h
|
||||
CLEANFILES+= errnum.h const.h
|
||||
|
||||
errnum.h: err.c
|
||||
${_MKTARGET_CREATE}
|
||||
rm -f ${.TARGET}
|
||||
(\
|
||||
echo '/* Do not edit this file, make creates it. */' ;\
|
||||
echo '#ifndef _h_sh_errnum' ;\
|
||||
echo '#define _h_sh_errnum' ;\
|
||||
egrep 'ERR_' ${.ALLSRC} | egrep '^#define' ;\
|
||||
echo '#endif /* _h_sh_errnum */' ;\
|
||||
) > ${.TARGET}
|
||||
|
||||
const.c: errnum.h
|
||||
const.h: const.c
|
||||
${_MKTARGET_CREATE}
|
||||
rm -f ${.TARGET}
|
||||
echo '/* Do not edit this file, make creates it. */' > ${.TARGET}
|
||||
${CC} -E ${CPPFLAGS} ${.ALLSRC} | egrep 'Char STR' | \
|
||||
${TOOL_SED} -e 's/Char \([a-zA-Z0-9_]*\)\(.*\)/extern Char \1[];/' | \
|
||||
sort >> ${.TARGET}
|
||||
|
||||
.if make(install)
|
||||
SUBDIR+=USD.doc
|
||||
.endif
|
||||
|
||||
# XXX Only GCC 4.1 problem
|
||||
.if defined(HAVE_GCC) && ${HAVE_GCC} == 4 && ${MACHINE_ARCH} == "vax"
|
||||
COPTS.parse.c+= -O0
|
||||
.endif
|
||||
COPTS.err.c = -Wno-format-nonliteral
|
||||
COPTS.printf.c = -Wno-format-nonliteral
|
||||
COPTS.proc.c = -Wno-format-nonliteral
|
||||
|
||||
.if !empty(DFLAGS:M*EDIT)
|
||||
LDADD+=-ledit -lterminfo -lutil
|
||||
DPADD+=${LIBEDIT} ${LIBUTIL}
|
||||
.else
|
||||
LDADD+=-lutil
|
||||
DPADD+=${LIBUTIL}
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
.include <bsd.subdir.mk>
|
||||
12
bin/csh/USD.doc/Makefile
Normal file
12
bin/csh/USD.doc/Makefile
Normal file
@@ -0,0 +1,12 @@
|
||||
# $NetBSD: Makefile,v 1.7 2007/10/18 18:26:31 tls Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 8/14/93
|
||||
|
||||
DIR= usd/04.csh
|
||||
SRCS= tabs csh.1 csh.2 csh.3 csh.4 csh.ap csh.g
|
||||
MACROS= -ms
|
||||
|
||||
paper.ps: ${SRCS}
|
||||
${TOOL_SOELIM} -I${.CURDIR} ${.ALLSRC} | \
|
||||
${TOOL_ROFF_PS} ${MACROS} > ${.TARGET}
|
||||
|
||||
.include <bsd.doc.mk>
|
||||
1010
bin/csh/USD.doc/csh.1
Normal file
1010
bin/csh/USD.doc/csh.1
Normal file
File diff suppressed because it is too large
Load Diff
1303
bin/csh/USD.doc/csh.2
Normal file
1303
bin/csh/USD.doc/csh.2
Normal file
File diff suppressed because it is too large
Load Diff
648
bin/csh/USD.doc/csh.3
Normal file
648
bin/csh/USD.doc/csh.3
Normal file
@@ -0,0 +1,648 @@
|
||||
.\" $NetBSD: csh.3,v 1.5 2003/08/07 09:05:08 agc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1980, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. 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.
|
||||
.\"
|
||||
.\" @(#)csh.3 8.1 (Berkeley) 6/8/93
|
||||
.\"
|
||||
.nr H1 2
|
||||
.NH
|
||||
Shell control structures and command scripts
|
||||
.NH 2
|
||||
Introduction
|
||||
.PP
|
||||
It is possible to place commands in files and to cause shells to be
|
||||
invoked to read and execute commands from these files,
|
||||
which are called
|
||||
.I "shell scripts."
|
||||
We here detail those features of the shell useful to the writers of such
|
||||
scripts.
|
||||
.NH 2
|
||||
Make
|
||||
.PP
|
||||
It is important to first note what shell scripts are
|
||||
.I not
|
||||
useful for.
|
||||
There is a program called
|
||||
.I make
|
||||
which is very useful for maintaining a group of related files
|
||||
or performing sets of operations on related files.
|
||||
For instance a large program consisting of one or more files
|
||||
can have its dependencies described in a
|
||||
.I makefile
|
||||
which contains definitions of the commands used to create these
|
||||
different files when changes occur.
|
||||
Definitions of the means for printing listings, cleaning up the directory
|
||||
in which the files reside, and installing the resultant programs
|
||||
are easily, and most appropriately placed in this
|
||||
.I makefile.
|
||||
This format is superior and preferable to maintaining a group of shell
|
||||
procedures to maintain these files.
|
||||
.PP
|
||||
Similarly when working on a document a
|
||||
.I makefile
|
||||
may be created which defines how different versions of the document
|
||||
are to be created and which options of
|
||||
.I nroff
|
||||
or
|
||||
.I troff
|
||||
are appropriate.
|
||||
.NH 2
|
||||
Invocation and the argv variable
|
||||
.PP
|
||||
A
|
||||
.I csh
|
||||
command script may be interpreted by saying
|
||||
.DS
|
||||
% csh script ...
|
||||
.DE
|
||||
where
|
||||
.I script
|
||||
is the name of the file containing a group of
|
||||
.I csh
|
||||
commands and
|
||||
`\&...' is replaced by a sequence of arguments.
|
||||
The shell places these arguments in the variable
|
||||
.I argv
|
||||
and then begins to read commands from the script.
|
||||
These parameters are then available through the same mechanisms
|
||||
which are used to reference any other shell variables.
|
||||
.PP
|
||||
If you make the file
|
||||
`script'
|
||||
executable by doing
|
||||
.DS
|
||||
chmod 755 script
|
||||
.DE
|
||||
and place a shell comment at the beginning of the shell script
|
||||
(i.e. begin the file with a `#' character)
|
||||
then a `/bin/csh' will automatically be invoked to execute `script' when
|
||||
you type
|
||||
.DS
|
||||
script
|
||||
.DE
|
||||
If the file does not begin with a `#' then the standard shell
|
||||
`/bin/sh' will be used to execute it.
|
||||
This allows you to convert your older shell scripts to use
|
||||
.I csh
|
||||
at your convenience.
|
||||
.NH 2
|
||||
Variable substitution
|
||||
.PP
|
||||
After each input line is broken into words and history substitutions
|
||||
are done on it, the input line is parsed into distinct commands.
|
||||
Before each command is executed a mechanism know as
|
||||
.I "variable substitution"
|
||||
is done on these words.
|
||||
Keyed by the character `$' this substitution replaces the names
|
||||
of variables by their values.
|
||||
Thus
|
||||
.DS
|
||||
echo $argv
|
||||
.DE
|
||||
when placed in a command script would cause the current value of the
|
||||
variable
|
||||
.I argv
|
||||
to be echoed to the output of the shell script.
|
||||
It is an error for
|
||||
.I argv
|
||||
to be unset at this point.
|
||||
.PP
|
||||
A number of notations are provided for accessing components and attributes
|
||||
of variables.
|
||||
The notation
|
||||
.DS
|
||||
$?name
|
||||
.DE
|
||||
expands to `1' if name is
|
||||
.I set
|
||||
or to `0'
|
||||
if name is not
|
||||
.I set.
|
||||
It is the fundamental mechanism used for checking whether particular
|
||||
variables have been assigned values.
|
||||
All other forms of reference to undefined variables cause errors.
|
||||
.PP
|
||||
The notation
|
||||
.DS
|
||||
$#name
|
||||
.DE
|
||||
expands to the number of elements in the variable
|
||||
.I name.
|
||||
Thus
|
||||
.DS
|
||||
% set argv=(a b c)
|
||||
% echo $?argv
|
||||
1
|
||||
% echo $#argv
|
||||
3
|
||||
% unset argv
|
||||
% echo $?argv
|
||||
0
|
||||
% echo $argv
|
||||
Undefined variable: argv.
|
||||
%
|
||||
.DE
|
||||
.PP
|
||||
It is also possible to access the components of a variable
|
||||
which has several values.
|
||||
Thus
|
||||
.DS
|
||||
$argv[1]
|
||||
.DE
|
||||
gives the first component of
|
||||
.I argv
|
||||
or in the example above `a'.
|
||||
Similarly
|
||||
.DS
|
||||
$argv[$#argv]
|
||||
.DE
|
||||
would give `c',
|
||||
and
|
||||
.DS
|
||||
$argv[1\-2]
|
||||
.DE
|
||||
would give `a b'. Other notations useful in shell scripts are
|
||||
.DS
|
||||
$\fIn\fR
|
||||
.DE
|
||||
where
|
||||
.I n
|
||||
is an integer as a shorthand for
|
||||
.DS
|
||||
$argv[\fIn\fR\|]
|
||||
.DE
|
||||
the
|
||||
.I n\|th
|
||||
parameter and
|
||||
.DS
|
||||
$*
|
||||
.DE
|
||||
which is a shorthand for
|
||||
.DS
|
||||
$argv
|
||||
.DE
|
||||
The form
|
||||
.DS
|
||||
$$
|
||||
.DE
|
||||
expands to the process number of the current shell.
|
||||
Since this process number is unique in the system it can
|
||||
be used in generation of unique temporary file names.
|
||||
The form
|
||||
.DS
|
||||
$<
|
||||
.DE
|
||||
is quite special and is replaced by the next line of input read from
|
||||
the shell's standard input (not the script it is reading). This is
|
||||
useful for writing shell scripts that are interactive, reading
|
||||
commands from the terminal, or even writing a shell script that
|
||||
acts as a filter, reading lines from its input file. Thus the sequence
|
||||
.DS
|
||||
echo 'yes or no?\ec'
|
||||
set a=($<)
|
||||
.DE
|
||||
would write out the prompt `yes or no?' without a newline and then
|
||||
read the answer into the variable `a'. In this case `$#a' would be
|
||||
`0' if either a blank line or end-of-file (^D) was typed.
|
||||
.PP
|
||||
One minor difference between `$\fIn\fR\|' and `$argv[\fIn\fR\|]'
|
||||
should be noted here.
|
||||
The form
|
||||
`$argv[\fIn\fR\|]'
|
||||
will yield an error if
|
||||
.I n
|
||||
is not in the range
|
||||
`1\-$#argv'
|
||||
while `$n'
|
||||
will never yield an out of range subscript error.
|
||||
This is for compatibility with the way older shells handled parameters.
|
||||
.PP
|
||||
Another important point is that it is never an error to give a subrange
|
||||
of the form `n\-'; if there are less than
|
||||
.I n
|
||||
components of the given variable then no words are substituted.
|
||||
A range of the form `m\-n' likewise returns an empty vector without giving
|
||||
an error when \fIm\fR exceeds the number of elements of the given variable,
|
||||
provided the subscript \fIn\fR is in range.
|
||||
.NH 2
|
||||
Expressions
|
||||
.PP
|
||||
In order for interesting shell scripts to be constructed it
|
||||
must be possible to evaluate expressions in the shell based on the
|
||||
values of variables.
|
||||
In fact, all the arithmetic operations of the language C are available
|
||||
in the shell
|
||||
with the same precedence that they have in C.
|
||||
In particular, the operations `==' and `!=' compare strings
|
||||
and the operators `&&' and `|\|\||' implement the boolean and/or operations.
|
||||
The special operators `=~' and `!~' are similar to `==' and `!=' except
|
||||
that the string on the right side can have pattern matching characters
|
||||
(like *, ? or []) and the test is whether the string on the left matches
|
||||
the pattern on the right.
|
||||
.PP
|
||||
The shell also allows file enquiries of the form
|
||||
.DS
|
||||
\-? filename
|
||||
.DE
|
||||
where `?' is replace by a number of single characters.
|
||||
For instance the expression primitive
|
||||
.DS
|
||||
\-e filename
|
||||
.DE
|
||||
tell whether the file
|
||||
`filename'
|
||||
exists.
|
||||
Other primitives test for read, write and execute access to the file,
|
||||
whether it is a directory, or has non-zero length.
|
||||
.PP
|
||||
It is possible to test whether a command terminates normally,
|
||||
by a primitive of the
|
||||
form `{ command }' which returns true, i.e. `1' if the command
|
||||
succeeds exiting normally with exit status 0, or `0' if the command
|
||||
terminates abnormally or with exit status non-zero.
|
||||
If more detailed information about the execution status of a command
|
||||
is required, it can be executed and the variable `$status' examined
|
||||
in the next command.
|
||||
Since `$status' is set by every command, it is very transient.
|
||||
It can be saved if it is inconvenient to use it only in the single
|
||||
immediately following command.
|
||||
.PP
|
||||
For a full list of expression components available see the manual
|
||||
section for the shell.
|
||||
.NH 2
|
||||
Sample shell script
|
||||
.PP
|
||||
A sample shell script which makes use of the expression mechanism
|
||||
of the shell and some of its control structure follows:
|
||||
.DS
|
||||
% cat copyc
|
||||
#
|
||||
# Copyc copies those C programs in the specified list
|
||||
# to the directory ~/backup if they differ from the files
|
||||
# already in ~/backup
|
||||
#
|
||||
set noglob
|
||||
foreach i ($argv)
|
||||
|
||||
if ($i !~ *.c) continue # not a .c file so do nothing
|
||||
|
||||
if (! \-r ~/backup/$i:t) then
|
||||
echo $i:t not in backup... not cp\e\'ed
|
||||
continue
|
||||
endif
|
||||
|
||||
cmp \-s $i ~/backup/$i:t # to set $status
|
||||
|
||||
if ($status != 0) then
|
||||
echo new backup of $i
|
||||
cp $i ~/backup/$i:t
|
||||
endif
|
||||
end
|
||||
.DE
|
||||
.PP
|
||||
This script makes use of the
|
||||
.I foreach
|
||||
command, which causes the shell to execute the commands between the
|
||||
.I foreach
|
||||
and the matching
|
||||
.I end
|
||||
for each of the values given between `(' and `)' with the named
|
||||
variable, in this case `i' set to successive values in the list.
|
||||
Within this loop we may use the command
|
||||
.I break
|
||||
to stop executing the loop
|
||||
and
|
||||
.I continue
|
||||
to prematurely terminate one iteration
|
||||
and begin the next.
|
||||
After the
|
||||
.I foreach
|
||||
loop the iteration variable
|
||||
(\fIi\fR in this case)
|
||||
has the value at the last iteration.
|
||||
.PP
|
||||
We set the variable
|
||||
.I noglob
|
||||
here to prevent filename expansion of the members of
|
||||
.I argv.
|
||||
This is a good idea, in general, if the arguments to a shell script
|
||||
are filenames which have already been expanded or if the arguments
|
||||
may contain filename expansion metacharacters.
|
||||
It is also possible to quote each use of a `$' variable expansion,
|
||||
but this is harder and less reliable.
|
||||
.PP
|
||||
The other control construct used here is a statement of the form
|
||||
.DS
|
||||
\fBif\fR ( expression ) \fBthen\fR
|
||||
command
|
||||
...
|
||||
\fBendif\fR
|
||||
.DE
|
||||
The placement of the keywords here is
|
||||
.B not
|
||||
flexible due to the current implementation of the shell.\(dg
|
||||
.FS
|
||||
\(dgThe following two formats are not currently acceptable to the shell:
|
||||
.sp
|
||||
.in +5
|
||||
.nf
|
||||
\fBif\fR ( expression ) # \fBWon't work!\fR
|
||||
\fBthen\fR
|
||||
command
|
||||
...
|
||||
\fBendif\fR
|
||||
.fi
|
||||
.in -5
|
||||
.sp
|
||||
and
|
||||
.sp
|
||||
.in +5
|
||||
.nf
|
||||
\fBif\fR ( expression ) \fBthen\fR command \fBendif\fR # \fBWon't work\fR
|
||||
.in -5
|
||||
.fi
|
||||
.FE
|
||||
.PP
|
||||
The shell does have another form of the if statement of the form
|
||||
.DS
|
||||
\fBif\fR ( expression ) \fBcommand\fR
|
||||
.DE
|
||||
which can be written
|
||||
.DS
|
||||
\fBif\fR ( expression ) \e
|
||||
command
|
||||
.DE
|
||||
Here we have escaped the newline for the sake of appearance.
|
||||
The command must not involve `\||\|', `&' or `;'
|
||||
and must not be another control command.
|
||||
The second form requires the final `\e' to
|
||||
.B immediately
|
||||
precede the end-of-line.
|
||||
.PP
|
||||
The more general
|
||||
.I if
|
||||
statements above also admit a sequence of
|
||||
.I else\-if
|
||||
pairs followed by a single
|
||||
.I else
|
||||
and an
|
||||
.I endif,
|
||||
e.g.:
|
||||
.DS
|
||||
\fBif\fR ( expression ) \fBthen\fR
|
||||
commands
|
||||
\fBelse\fR \fBif\fR (expression ) \fBthen\fR
|
||||
commands
|
||||
\&...
|
||||
|
||||
\fBelse\fR
|
||||
commands
|
||||
\fBendif\fR
|
||||
.DE
|
||||
.PP
|
||||
Another important mechanism used in shell scripts is the `:' modifier.
|
||||
We can use the modifier `:r' here to extract a root of a filename or
|
||||
`:e' to extract the
|
||||
.I extension.
|
||||
Thus if the variable
|
||||
.I i
|
||||
has the value
|
||||
`/mnt/foo.bar'
|
||||
then
|
||||
.sp
|
||||
.in +5
|
||||
.nf
|
||||
% echo $i $i:r $i:e
|
||||
/mnt/foo.bar /mnt/foo bar
|
||||
%
|
||||
.sp
|
||||
.in -5
|
||||
.fi
|
||||
shows how the `:r' modifier strips off the trailing `.bar' and the
|
||||
the `:e' modifier leaves only the `bar'.
|
||||
Other modifiers will take off the last component of a pathname leaving
|
||||
the head `:h' or all but the last component of a pathname leaving the
|
||||
tail `:t'.
|
||||
These modifiers are fully described in the
|
||||
.I csh
|
||||
manual pages in the User's Reference Manual.
|
||||
It is also possible to use the
|
||||
.I "command substitution"
|
||||
mechanism described in the next major section to perform modifications
|
||||
on strings to then reenter the shell's environment.
|
||||
Since each usage of this mechanism involves the creation of a new process,
|
||||
it is much more expensive to use than the `:' modification mechanism.\(dd
|
||||
.FS
|
||||
\(dd It is also important to note that
|
||||
the current implementation of the shell limits the number of `:' modifiers
|
||||
on a `$' substitution to 1.
|
||||
Thus
|
||||
.sp
|
||||
.nf
|
||||
.in +5
|
||||
% echo $i $i:h:t
|
||||
/a/b/c /a/b:t
|
||||
%
|
||||
.in -5
|
||||
.fi
|
||||
.sp
|
||||
does not do what one would expect.
|
||||
.FE
|
||||
Finally, we note that the character `#' lexically introduces a shell
|
||||
comment in shell scripts (but not from the terminal).
|
||||
All subsequent characters on the input line after a `#' are discarded
|
||||
by the shell.
|
||||
This character can be quoted using `\'' or `\e' to place it in
|
||||
an argument word.
|
||||
.NH 2
|
||||
Other control structures
|
||||
.PP
|
||||
The shell also has control structures
|
||||
.I while
|
||||
and
|
||||
.I switch
|
||||
similar to those of C.
|
||||
These take the forms
|
||||
.DS
|
||||
\fBwhile\fR ( expression )
|
||||
commands
|
||||
\fBend\fR
|
||||
.DE
|
||||
and
|
||||
.DS
|
||||
\fBswitch\fR ( word )
|
||||
|
||||
\fBcase\fR str1:
|
||||
commands
|
||||
\fBbreaksw\fR
|
||||
|
||||
\& ...
|
||||
|
||||
\fBcase\fR strn:
|
||||
commands
|
||||
\fBbreaksw\fR
|
||||
|
||||
\fBdefault:\fR
|
||||
commands
|
||||
\fBbreaksw\fR
|
||||
|
||||
\fBendsw\fR
|
||||
.DE
|
||||
For details see the manual section for
|
||||
.I csh.
|
||||
C programmers should note that we use
|
||||
.I breaksw
|
||||
to exit from a
|
||||
.I switch
|
||||
while
|
||||
.I break
|
||||
exits a
|
||||
.I while
|
||||
or
|
||||
.I foreach
|
||||
loop.
|
||||
A common mistake to make in
|
||||
.I csh
|
||||
scripts is to use
|
||||
.I break
|
||||
rather than
|
||||
.I breaksw
|
||||
in switches.
|
||||
.PP
|
||||
Finally,
|
||||
.I csh
|
||||
allows a
|
||||
.I goto
|
||||
statement, with labels looking like they do in C, i.e.:
|
||||
.DS
|
||||
loop:
|
||||
commands
|
||||
\fBgoto\fR loop
|
||||
.DE
|
||||
.NH 2
|
||||
Supplying input to commands
|
||||
.PP
|
||||
Commands run from shell scripts receive by default the standard
|
||||
input of the shell which is running the script.
|
||||
This is different from previous shells running
|
||||
under \s-2UNIX\s0. It allows shell scripts to fully participate
|
||||
in pipelines, but mandates extra notation for commands which are to take
|
||||
inline data.
|
||||
.PP
|
||||
Thus we need a metanotation for supplying inline data to commands in
|
||||
shell scripts.
|
||||
As an example, consider this script which runs the editor to
|
||||
delete leading blanks from the lines in each argument file:
|
||||
.DS
|
||||
% cat deblank
|
||||
# deblank \-\- remove leading blanks
|
||||
foreach i ($argv)
|
||||
ed \- $i << \'EOF\'
|
||||
1,$s/^[ ]*//
|
||||
w
|
||||
q
|
||||
\&\'EOF\'
|
||||
end
|
||||
%
|
||||
.DE
|
||||
The notation `<< \'EOF\''
|
||||
means that the standard input for the
|
||||
.I ed
|
||||
command is to come from the text in the shell script file
|
||||
up to the next line consisting of exactly `\'EOF\''.
|
||||
The fact that the `EOF' is enclosed in `\'' characters, i.e. quoted,
|
||||
causes the shell to not perform variable substitution on the
|
||||
intervening lines.
|
||||
In general, if any part of the word following the `<<' which the
|
||||
shell uses to terminate the text to be given to the command is quoted
|
||||
then these substitutions will not be performed.
|
||||
In this case since we used the form `1,$' in our editor script
|
||||
we needed to insure that this `$' was not variable substituted.
|
||||
We could also have insured this by preceding the `$' here with a `\e',
|
||||
i.e.:
|
||||
.DS
|
||||
1,\e$s/^[ ]*//
|
||||
.DE
|
||||
but quoting the `EOF' terminator is a more reliable way of achieving the
|
||||
same thing.
|
||||
.NH 2
|
||||
Catching interrupts
|
||||
.PP
|
||||
If our shell script creates temporary files, we may wish to catch
|
||||
interruptions of the shell script so that we can clean up
|
||||
these files.
|
||||
We can then do
|
||||
.DS
|
||||
onintr label
|
||||
.DE
|
||||
where
|
||||
.I label
|
||||
is a label in our program.
|
||||
If an interrupt is received the shell will do a
|
||||
`goto label'
|
||||
and we can remove the temporary files and then do an
|
||||
.I exit
|
||||
command (which is built in to the shell)
|
||||
to exit from the shell script.
|
||||
If we wish to exit with a non-zero status we can do
|
||||
.DS
|
||||
exit(1)
|
||||
.DE
|
||||
e.g. to exit with status `1'.
|
||||
.NH 2
|
||||
What else?
|
||||
.PP
|
||||
There are other features of the shell useful to writers of shell
|
||||
procedures.
|
||||
The
|
||||
.I verbose
|
||||
and
|
||||
.I echo
|
||||
options and the related
|
||||
.I \-v
|
||||
and
|
||||
.I \-x
|
||||
command line options can be used to help trace the actions of the shell.
|
||||
The
|
||||
.I \-n
|
||||
option causes the shell only to read commands and not to execute
|
||||
them and may sometimes be of use.
|
||||
.PP
|
||||
One other thing to note is that
|
||||
.I csh
|
||||
will not execute shell scripts which do not begin with the
|
||||
character `#', that is shell scripts that do not begin with a comment.
|
||||
Similarly, the `/bin/sh' on your system may well defer to `csh'
|
||||
to interpret shell scripts which begin with `#'.
|
||||
This allows shell scripts for both shells to live in harmony.
|
||||
.PP
|
||||
There is also another quotation mechanism using `"' which allows
|
||||
only some of the expansion mechanisms we have so far discussed to occur
|
||||
on the quoted string and serves to make this string into a single word
|
||||
as `\'' does.
|
||||
.bp
|
||||
176
bin/csh/USD.doc/csh.4
Normal file
176
bin/csh/USD.doc/csh.4
Normal file
@@ -0,0 +1,176 @@
|
||||
.\" $NetBSD: csh.4,v 1.4 2003/08/07 09:05:08 agc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1980, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. 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.
|
||||
.\"
|
||||
.\" @(#)csh.4 8.1 (Berkeley) 6/8/93
|
||||
.\"
|
||||
.nr H1 3
|
||||
.NH
|
||||
Other, less commonly used, shell features
|
||||
.NH 2
|
||||
Loops at the terminal; variables as vectors
|
||||
.PP
|
||||
It is occasionally useful to use the
|
||||
.I foreach
|
||||
control structure at the terminal to aid in performing a number
|
||||
of similar commands.
|
||||
For instance, there were at one point three shells in use on the Cory \s-2UNIX\s0
|
||||
system at Cory Hall,
|
||||
`/bin/sh',
|
||||
`/bin/nsh',
|
||||
and
|
||||
`/bin/csh'.
|
||||
To count the number of persons using each shell one could have issued
|
||||
the commands
|
||||
.DS
|
||||
% grep \-c csh$ /etc/passwd
|
||||
27
|
||||
% grep \-c nsh$ /etc/passwd
|
||||
128
|
||||
% grep \-c \-v sh$ /etc/passwd
|
||||
430
|
||||
%
|
||||
.DE
|
||||
Since these commands are very similar we can use
|
||||
.I foreach
|
||||
to do this more easily.
|
||||
.DS
|
||||
% foreach i (\'sh$\' \'csh$\' \'\-v sh$\')
|
||||
? grep \-c $i /etc/passwd
|
||||
? end
|
||||
27
|
||||
128
|
||||
430
|
||||
%
|
||||
.DE
|
||||
Note here that the shell prompts for
|
||||
input with `? ' when reading the body of the loop.
|
||||
.PP
|
||||
Very useful with loops are variables which contain lists of filenames
|
||||
or other words.
|
||||
You can, for example, do
|
||||
.DS
|
||||
% set a=(\`ls\`)
|
||||
% echo $a
|
||||
csh.n csh.rm
|
||||
% ls
|
||||
csh.n
|
||||
csh.rm
|
||||
% echo $#a
|
||||
2
|
||||
%
|
||||
.DE
|
||||
The
|
||||
.I set
|
||||
command here gave the variable
|
||||
.I a
|
||||
a list of all the filenames in the current directory as value.
|
||||
We can then iterate over these names to perform any chosen function.
|
||||
.PP
|
||||
The output of a command within `\`' characters is converted by
|
||||
the shell to a list of words.
|
||||
You can also place the `\`' quoted string within `"' characters
|
||||
to take each (non-empty) line as a component of the variable;
|
||||
preventing the lines from being split into words at blanks and tabs.
|
||||
A modifier `:x' exists which can be used later to expand each component
|
||||
of the variable into another variable splitting it into separate words
|
||||
at embedded blanks and tabs.
|
||||
.NH 2
|
||||
Braces { ... } in argument expansion
|
||||
.PP
|
||||
Another form of filename expansion, alluded
|
||||
to before involves the characters `{' and `}'.
|
||||
These characters specify that the contained strings, separated by `,'
|
||||
are to be consecutively substituted into the containing characters
|
||||
and the results expanded left to right.
|
||||
Thus
|
||||
.DS
|
||||
A{str1,str2,...strn}B
|
||||
.DE
|
||||
expands to
|
||||
.DS
|
||||
Astr1B Astr2B ... AstrnB
|
||||
.DE
|
||||
This expansion occurs before the other filename expansions, and may
|
||||
be applied recursively (i.e. nested).
|
||||
The results of each expanded string are sorted separately, left
|
||||
to right order being preserved.
|
||||
The resulting filenames are not required to exist if no other expansion
|
||||
mechanisms are used.
|
||||
This means that this mechanism can be used to generate arguments which are
|
||||
not filenames, but which have common parts.
|
||||
.PP
|
||||
A typical use of this would be
|
||||
.DS
|
||||
mkdir ~/{hdrs,retrofit,csh}
|
||||
.DE
|
||||
to make subdirectories `hdrs', `retrofit' and `csh'
|
||||
in your home directory.
|
||||
This mechanism is most useful when the common prefix is longer
|
||||
than in this example, i.e.
|
||||
.DS
|
||||
chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}}
|
||||
.DE
|
||||
.NH 2
|
||||
Command substitution
|
||||
.PP
|
||||
A command enclosed in `\`' characters is replaced, just before
|
||||
filenames are expanded, by the output from that command.
|
||||
Thus it is possible to do
|
||||
.DS
|
||||
set pwd=\`pwd\`
|
||||
.DE
|
||||
to save the current directory in the variable
|
||||
.I pwd
|
||||
or to do
|
||||
.DS
|
||||
ex \`grep \-l TRACE *.c\`
|
||||
.DE
|
||||
to run the editor
|
||||
.I ex
|
||||
supplying as arguments those files whose names end in `.c'
|
||||
which have the string `TRACE' in them.*
|
||||
.FS
|
||||
*Command expansion also occurs in input redirected with `<<'
|
||||
and within `"' quotations.
|
||||
Refer to the shell manual section for full details.
|
||||
.FE
|
||||
.NH 2
|
||||
Other details not covered here
|
||||
.PP
|
||||
In particular circumstances it may be necessary to know the exact
|
||||
nature and order of different substitutions performed by the shell.
|
||||
The exact meaning of certain combinations of quotations is also
|
||||
occasionally important.
|
||||
These are detailed fully in its manual section.
|
||||
.PP
|
||||
The shell has a number of command line option flags mostly of use
|
||||
in writing \s-2UNIX\s0 programs,
|
||||
and debugging shell scripts.
|
||||
See the csh(1) manual section for a list of these options.
|
||||
.bp
|
||||
93
bin/csh/USD.doc/csh.ap
Normal file
93
bin/csh/USD.doc/csh.ap
Normal file
@@ -0,0 +1,93 @@
|
||||
.\" $NetBSD: csh.ap,v 1.1 2007/10/18 18:26:31 tls Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1980, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. 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.
|
||||
.\"
|
||||
.\" @(#)csh.a 8.1 (Berkeley) 6/8/93
|
||||
.\"
|
||||
.SH
|
||||
Appendix \- Special characters
|
||||
.LP
|
||||
The following table lists the special characters of
|
||||
.I csh
|
||||
and the \s-2UNIX\s0 system, giving for each the section(s) in which it
|
||||
is discussed.
|
||||
A number of these characters also have special meaning in expressions.
|
||||
See the
|
||||
.I csh
|
||||
manual section
|
||||
for a complete list.
|
||||
.ta .75i 1.5i 2.25i
|
||||
.LP
|
||||
Syntactic metacharacters
|
||||
.DS
|
||||
; 2.4 separates commands to be executed sequentially
|
||||
| 1.5 separates commands in a pipeline
|
||||
( ) 2.2,3.6 brackets expressions and variable values
|
||||
& 2.5 follows commands to be executed without waiting for completion
|
||||
.DE
|
||||
.LP
|
||||
Filename metacharacters
|
||||
.DS
|
||||
/ 1.6 separates components of a file's pathname
|
||||
\&. 1.6 separates root parts of a file name from extensions
|
||||
? 1.6 expansion character matching any single character
|
||||
* 1.6 expansion character matching any sequence of characters
|
||||
[ ] 1.6 expansion sequence matching any single character from a set
|
||||
~ 1.6 used at the beginning of a filename to indicate home directories
|
||||
{ } 4.2 used to specify groups of arguments with common parts
|
||||
.DE
|
||||
.LP
|
||||
Quotation metacharacters
|
||||
.DS
|
||||
\e 1.7 prevents meta-meaning of following single character
|
||||
\' 1.7 prevents meta-meaning of a group of characters
|
||||
" 4.3 like \', but allows variable and command expansion
|
||||
.DE
|
||||
.LP
|
||||
Input/output metacharacters
|
||||
.DS
|
||||
< 1.5 indicates redirected input
|
||||
> 1.3 indicates redirected output
|
||||
.DE
|
||||
.LP
|
||||
Expansion/substitution metacharacters
|
||||
.DS
|
||||
$ 3.4 indicates variable substitution
|
||||
! 2.3 indicates history substitution
|
||||
: 3.6 precedes substitution modifiers
|
||||
^ 2.3 used in special forms of history substitution
|
||||
\` 4.3 indicates command substitution
|
||||
.DE
|
||||
.LP
|
||||
Other metacharacters
|
||||
.DS
|
||||
# 1.3,3.6 begins scratch file names; indicates shell comments
|
||||
\- 1.2 prefixes option (flag) arguments to commands
|
||||
% 2.6 prefixes job name specifications
|
||||
.DE
|
||||
.bp
|
||||
1719
bin/csh/USD.doc/csh.g
Normal file
1719
bin/csh/USD.doc/csh.g
Normal file
File diff suppressed because it is too large
Load Diff
32
bin/csh/USD.doc/tabs
Normal file
32
bin/csh/USD.doc/tabs
Normal file
@@ -0,0 +1,32 @@
|
||||
.\" $NetBSD: tabs,v 1.4 2003/08/07 09:05:09 agc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1980, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. 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.
|
||||
.\"
|
||||
.\" @(#)tabs 8.1 (Berkeley) 6/8/93
|
||||
.\"
|
||||
.ta 5n 10n 15n 20n 25n 30n 35n 40n 45n 50n 55n 60n 65n 70n 75n 80n
|
||||
91
bin/csh/alloc.c
Normal file
91
bin/csh/alloc.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/* $NetBSD: alloc.c,v 1.13 2013/01/22 19:28:00 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1983, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)alloc.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: alloc.c,v 1.13 2013/01/22 19:28:00 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
ptr_t
|
||||
Malloc(size_t n)
|
||||
{
|
||||
ptr_t ptr;
|
||||
|
||||
if ((ptr = malloc(n)) == (ptr_t) 0) {
|
||||
child++;
|
||||
stderror(ERR_NOMEM);
|
||||
}
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
ptr_t
|
||||
Realloc(ptr_t p, size_t n)
|
||||
{
|
||||
ptr_t ptr;
|
||||
|
||||
if ((ptr = realloc(p, n)) == (ptr_t) 0) {
|
||||
child++;
|
||||
stderror(ERR_NOMEM);
|
||||
}
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
ptr_t
|
||||
Calloc(size_t s, size_t n)
|
||||
{
|
||||
ptr_t ptr;
|
||||
|
||||
if ((ptr = calloc(s, n)) == (ptr_t) 0) {
|
||||
child++;
|
||||
stderror(ERR_NOMEM);
|
||||
}
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
void
|
||||
Free(ptr_t p)
|
||||
{
|
||||
if (p)
|
||||
free(p);
|
||||
}
|
||||
315
bin/csh/char.c
Normal file
315
bin/csh/char.c
Normal file
@@ -0,0 +1,315 @@
|
||||
/* $NetBSD: char.c,v 1.10 2012/01/19 02:42:53 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)char.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: char.c,v 1.10 2012/01/19 02:42:53 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include "char.h"
|
||||
|
||||
/* on default same as original map */
|
||||
unsigned short _cmap[256] = {
|
||||
/* 0 nul 1 soh 2 stx 3 etx */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* 4 eot 5 enq 6 ack 7 bel */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* 8 bs 9 ht 10 nl 11 vt */
|
||||
_CTR, _CTR|_SP|_META, _CTR|_NL|_META, _CTR,
|
||||
|
||||
/* 12 np 13 cr 14 so 15 si */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* 16 dle 17 dc1 18 dc2 19 dc3 */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* 20 dc4 21 nak 22 syn 23 etb */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* 24 can 25 em 26 sub 27 esc */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* 28 fs 29 gs 30 rs 31 us */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* 32 sp 33 ! 34 " 35 # */
|
||||
_SP|_META, _PUN, _QF|_PUN, _META|_PUN,
|
||||
|
||||
/* 36 $ 37 % 38 & 39 ' */
|
||||
_DOL|_PUN, _PUN, _META|_CMD|_PUN,_QF|_PUN,
|
||||
|
||||
/* 40 ( 41 ) 42 * 43 + */
|
||||
_META|_CMD|_PUN,_META|_PUN, _GLOB|_PUN, _PUN,
|
||||
|
||||
/* 44 , 45 - 46 . 47 / */
|
||||
_PUN, _PUN, _PUN, _PUN,
|
||||
|
||||
/* 48 0 49 1 50 2 51 3 */
|
||||
_DIG|_XD, _DIG|_XD, _DIG|_XD, _DIG|_XD,
|
||||
|
||||
/* 52 4 53 5 54 6 55 7 */
|
||||
_DIG|_XD, _DIG|_XD, _DIG|_XD, _DIG|_XD,
|
||||
|
||||
/* 56 8 57 9 58 : 59 ; */
|
||||
_DIG|_XD, _DIG|_XD, _PUN, _META|_CMD|_PUN,
|
||||
|
||||
/* 60 < 61 = 62 > 63 ? */
|
||||
_META|_PUN, _PUN, _META|_PUN, _GLOB|_PUN,
|
||||
|
||||
/* 64 @ 65 A 66 B 67 C */
|
||||
_PUN, _LET|_UP|_XD, _LET|_UP|_XD, _LET|_UP|_XD,
|
||||
|
||||
/* 68 D 69 E 70 F 71 G */
|
||||
_LET|_UP|_XD, _LET|_UP|_XD, _LET|_UP|_XD, _LET|_UP,
|
||||
|
||||
/* 72 H 73 I 74 J 75 K */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* 76 L 77 M 78 N 79 O */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* 80 P 81 Q 82 R 83 S */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* 84 T 85 U 86 V 87 W */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* 88 X 89 Y 90 Z 91 [ */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _GLOB|_PUN,
|
||||
|
||||
/* 92 \ 93 ] 94 ^ 95 _ */
|
||||
_ESC|_PUN, _PUN, _PUN, _PUN,
|
||||
|
||||
/* 96 ` 97 a 98 b 99 c */
|
||||
_QB|_GLOB|_META|_PUN, _LET|_LOW|_XD, _LET|_LOW|_XD, _LET|_LOW|_XD,
|
||||
|
||||
/* 100 d 101 e 102 f 103 g */
|
||||
_LET|_LOW|_XD, _LET|_LOW|_XD, _LET|_LOW|_XD, _LET|_LOW,
|
||||
|
||||
/* 104 h 105 i 106 j 107 k */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* 108 l 109 m 110 n 111 o */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* 112 p 113 q 114 r 115 s */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* 116 t 117 u 118 v 119 w */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* 120 x 121 y 122 z 123 { */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _GLOB|_PUN,
|
||||
|
||||
/* 124 | 125 } 126 ~ 127 del */
|
||||
_META|_CMD|_PUN,_PUN, _PUN, _CTR,
|
||||
|
||||
#ifdef SHORT_STRINGS
|
||||
/****************************************************************/
|
||||
/* 128 - 255 The below is supposedly ISO 8859/1 */
|
||||
/****************************************************************/
|
||||
/* 128 (undef) 129 (undef) 130 (undef) 131 (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* 132 (undef) 133 (undef) 134 (undef) 135 (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* 136 (undef) 137 (undef) 138 (undef) 139 (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* 140 (undef) 141 (undef) 142 (undef) 143 (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* 144 (undef) 145 (undef) 146 (undef) 147 (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* 148 (undef) 149 (undef) 150 (undef) 151 (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* 152 (undef) 153 (undef) 154 (undef) 155 (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* 156 (undef) 157 (undef) 158 (undef) 159 (undef) */
|
||||
_CTR, _CTR, _CTR, _CTR,
|
||||
|
||||
/* 160 nobreakspace 161 exclamdown 162 cent 163 sterling */
|
||||
_PUN, /* XXX */ _PUN, _PUN, _PUN,
|
||||
|
||||
/* 164 currency 165 yen 166 brokenbar 167 section */
|
||||
_PUN, _PUN, _PUN, _PUN,
|
||||
|
||||
/* 168 diaeresis 169 copyright 170 ordfeminine 171 guillemotleft*/
|
||||
_PUN, _PUN, _PUN, _PUN,
|
||||
|
||||
/* 172 notsign 173 hyphen 174 registered 175 macron */
|
||||
_PUN, _PUN, _PUN, _PUN,
|
||||
|
||||
/* 176 degree 177 plusminus 178 twosuperior 179 threesuperior*/
|
||||
_PUN, _PUN, _PUN, _PUN,
|
||||
|
||||
/* 180 acute 181 mu 182 paragraph 183 periodcentered*/
|
||||
_PUN, _PUN, /*XXX*/ _PUN, _PUN,
|
||||
|
||||
/* 184 cedilla 185 onesuperior 186 masculine 187 guillemotright*/
|
||||
_PUN, _PUN, _PUN, _PUN,
|
||||
|
||||
/* 188 onequarter 189 onehalf 190 threequarters 191 questiondown*/
|
||||
_PUN, _PUN, _PUN, _PUN,
|
||||
|
||||
/* 192 Agrave 193 Aacute 194 Acircumflex 195 Atilde */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* 196 Adiaeresis 197 Aring 198 AE 199 Ccedilla */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* 200 Egrave 201 Eacute 202 Ecircumflex 203 Ediaeresis */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* 204 Igrave 205 Iacute 206 Icircumflex 207 Idiaeresis */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* 208 ETH 209 Ntilde 210 Ograve 211 Oacute */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* 212 Ocircumflex 213 Otilde 214 Odiaeresis 215 multiply */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _PUN,
|
||||
|
||||
/* 216 Ooblique 217 Ugrave 218 Uacute 219 Ucircumflex */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_UP,
|
||||
|
||||
/* 220 Udiaeresis 221 Yacute 222 THORN 223 ssharp */
|
||||
_LET|_UP, _LET|_UP, _LET|_UP, _LET|_LOW,
|
||||
|
||||
/* 224 agrave 225 aacute 226 acircumflex 227 atilde */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* 228 adiaeresis 229 aring 230 ae 231 ccedilla */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* 232 egrave 233 eacute 234 ecircumflex 235 ediaeresis */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* 236 igrave 237 iacute 238 icircumflex 239 idiaeresis */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* 240 eth 241 ntilde 242 ograve 243 oacute */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* 244 ocircumflex 245 otilde 246 odiaeresis 247 division */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _PUN,
|
||||
|
||||
/* 248 oslash 249 ugrave 250 uacute 251 ucircumflex */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
|
||||
/* 252 udiaeresis 253 yacute 254 thorn 255 ydiaeresis */
|
||||
_LET|_LOW, _LET|_LOW, _LET|_LOW, _LET|_LOW,
|
||||
#endif /* SHORT_STRINGS */
|
||||
};
|
||||
|
||||
#ifndef NLS
|
||||
/* _cmap_lower, _cmap_upper for ISO 8859/1 */
|
||||
|
||||
unsigned char _cmap_lower[256] = {
|
||||
0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
|
||||
0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
|
||||
0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
|
||||
0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
|
||||
0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
|
||||
0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
|
||||
0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
|
||||
0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
|
||||
0100, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
|
||||
0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
|
||||
0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
|
||||
0170, 0171, 0172, 0133, 0134, 0135, 0136, 0137,
|
||||
0140, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
|
||||
0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
|
||||
0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
|
||||
0170, 0171, 0172, 0173, 0174, 0175, 0176, 0177,
|
||||
0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
|
||||
0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
|
||||
0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
|
||||
0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
|
||||
0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
|
||||
0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
|
||||
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
|
||||
0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
|
||||
0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
|
||||
0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
|
||||
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0327,
|
||||
0370, 0371, 0372, 0373, 0374, 0375, 0376, 0337,
|
||||
0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
|
||||
0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
|
||||
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
|
||||
0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
|
||||
};
|
||||
|
||||
unsigned char _cmap_upper[256] = {
|
||||
0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
|
||||
0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
|
||||
0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
|
||||
0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
|
||||
0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
|
||||
0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
|
||||
0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
|
||||
0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
|
||||
0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
|
||||
0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
|
||||
0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
|
||||
0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
|
||||
0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
|
||||
0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
|
||||
0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
|
||||
0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
|
||||
0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
|
||||
0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
|
||||
0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
|
||||
0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
|
||||
0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
|
||||
0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
|
||||
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
|
||||
0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
|
||||
0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
|
||||
0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
|
||||
0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
|
||||
0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
|
||||
0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
|
||||
0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
|
||||
0320, 0321, 0322, 0323, 0324, 0325, 0326, 0367,
|
||||
0330, 0331, 0332, 0333, 0334, 0335, 0336, 0377,
|
||||
};
|
||||
#endif /* NLS */
|
||||
100
bin/csh/char.h
Normal file
100
bin/csh/char.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/* $NetBSD: char.h,v 1.9 2012/01/19 02:42:53 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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.
|
||||
*
|
||||
* @(#)char.h 8.1 (Berkeley) 5/31/93
|
||||
*/
|
||||
|
||||
#ifndef _CHAR_H_
|
||||
#define _CHAR_H_
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
extern unsigned short _cmap[];
|
||||
|
||||
#ifndef NLS
|
||||
extern unsigned char _cmap_lower[], _cmap_upper[];
|
||||
|
||||
#endif
|
||||
|
||||
#define _QF 0x0001 /* '" (Forward quotes) */
|
||||
#define _QB 0x0002 /* ` (Backquote) */
|
||||
#define _SP 0x0004 /* space and tab */
|
||||
#define _NL 0x0008 /* \n */
|
||||
#define _META 0x0010 /* lex meta characters, sp #'`";&<>()|\t\n */
|
||||
#define _GLOB 0x0020 /* glob characters, *?{[` */
|
||||
#define _ESC 0x0040 /* \ */
|
||||
#define _DOL 0x0080 /* $ */
|
||||
#define _DIG 0x0100 /* 0-9 */
|
||||
#define _LET 0x0200 /* a-z, A-Z, _ */
|
||||
#define _UP 0x0400 /* A-Z */
|
||||
#define _LOW 0x0800 /* a-z */
|
||||
#define _XD 0x1000 /* 0-9, a-f, A-F */
|
||||
#define _CMD 0x2000 /* lex end of command chars, ;&(|` */
|
||||
#define _CTR 0x4000 /* control */
|
||||
#define _PUN 0x8000 /* punctuation */
|
||||
|
||||
#define cmap(c, bits) \
|
||||
(((c) & QUOTE) ? 0 : (_cmap[(unsigned char)(c)] & (bits)))
|
||||
|
||||
#define isglob(c) cmap(c, _GLOB)
|
||||
#define isspc(c) cmap(c, _SP)
|
||||
#define ismeta(c) cmap(c, _META)
|
||||
#define iscmdmeta(c) cmap(c, _CMD)
|
||||
#define letter(c) (((c) & QUOTE) ? 0 : \
|
||||
(isalpha((unsigned char) (c)) || (c) == '_'))
|
||||
#define alnum(c) (((c) & QUOTE) ? 0 : \
|
||||
(isalnum((unsigned char) (c)) || (c) == '_'))
|
||||
#ifdef NLS
|
||||
#define Isspace(c) (((c) & QUOTE) ? 0 : isspace((unsigned char) (c)))
|
||||
#define Isdigit(c) (((c) & QUOTE) ? 0 : isdigit((unsigned char) (c)))
|
||||
#define Isalpha(c) (((c) & QUOTE) ? 0 : isalpha((unsigned char) (c)))
|
||||
#define Islower(c) (((c) & QUOTE) ? 0 : islower((unsigned char) (c)))
|
||||
#define Isupper(c) (((c) & QUOTE) ? 0 : isupper((unsigned char) (c)))
|
||||
#define Tolower(c) (((c) & QUOTE) ? 0 : tolower((unsigned char) (c)))
|
||||
#define Toupper(c) (((c) & QUOTE) ? 0 : toupper((unsigned char) (c)))
|
||||
#define Isxdigit(c) (((c) & QUOTE) ? 0 : isxdigit((unsigned char) (c)))
|
||||
#define Isalnum(c) (((c) & QUOTE) ? 0 : isalnum((unsigned char) (c)))
|
||||
#define Iscntrl(c) (((c) & QUOTE) ? 0 : iscntrl((unsigned char) (c)))
|
||||
#define Isprint(c) (((c) & QUOTE) ? 0 : isprint((unsigned char) (c)))
|
||||
#else
|
||||
#define Isspace(c) cmap(c, _SP|_NL)
|
||||
#define Isdigit(c) cmap(c, _DIG)
|
||||
#define Isalpha(c) (cmap(c,_LET) && !(((c) & META) && AsciiOnly))
|
||||
#define Islower(c) (cmap(c,_LOW) && !(((c) & META) && AsciiOnly))
|
||||
#define Isupper(c) (cmap(c, _UP) && !(((c) & META) && AsciiOnly))
|
||||
#define Tolower(c) (_cmap_lower[(unsigned char)(c)])
|
||||
#define Toupper(c) (_cmap_upper[(unsigned char)(c)])
|
||||
#define Isxdigit(c) cmap(c, _XD)
|
||||
#define Isalnum(c) (cmap(c, _DIG|_LET) && !(((c) & META) && AsciiOnly))
|
||||
#define Iscntrl(c) (cmap(c,_CTR) && !(((c) & META) && AsciiOnly))
|
||||
#define Isprint(c) (!cmap(c,_CTR) && !(((c) & META) && AsciiOnly))
|
||||
#endif
|
||||
|
||||
#endif /* !_CHAR_H_ */
|
||||
164
bin/csh/const.c
Normal file
164
bin/csh/const.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/* $NetBSD: const.c,v 1.10 2013/01/22 20:35:29 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)const.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: const.c,v 1.10 2013/01/22 20:35:29 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* tc.const.c: String constants for csh.
|
||||
*/
|
||||
|
||||
#include "csh.h"
|
||||
|
||||
Char STR0[] = { '0', '\0' };
|
||||
Char STR1[] = { '1', '\0' };
|
||||
Char STRHOME[] = { 'H', 'O', 'M', 'E', '\0' };
|
||||
Char STRLANG[] = { 'L', 'A', 'N', 'G', '\0' };
|
||||
Char STRLC_CTYPE[] = { 'L', 'C', '_', 'C', 'T', 'Y', 'P', 'E' ,'\0' };
|
||||
Char STRLOGNAME[] = { 'L', 'O', 'G', 'N', 'A', 'M', 'E', '\0' };
|
||||
Char STRLbrace[] = { '{', '\0' };
|
||||
Char STRLparen[] = { '(', '\0' };
|
||||
Char STRLparensp[] = { '(', ' ', '\0' };
|
||||
Char STRNULL[] = { '\0' };
|
||||
Char STRPATH[] = { 'P', 'A', 'T', 'H', '\0' };
|
||||
Char STRPWD[] = { 'P', 'W', 'D', '\0' };
|
||||
Char STRQNULL[] = { '\0' | QUOTE, '\0' };
|
||||
Char STRRbrace[] = { '}', '\0' };
|
||||
Char STRspRparen[] = { ' ', ')', '\0' };
|
||||
Char STRTERM[] = { 'T', 'E', 'R', 'M', '\0' };
|
||||
Char STRUSER[] = { 'U', 'S', 'E', 'R', '\0' };
|
||||
Char STRalias[] = { 'a', 'l', 'i', 'a', 's', '\0' };
|
||||
Char STRand[] = { '&', '\0' };
|
||||
Char STRand2[] = { '&', '&', '\0' };
|
||||
Char STRaout[] = { 'a', '.', 'o', 'u', 't', '\0' };
|
||||
Char STRargv[] = { 'a', 'r', 'g', 'v', '\0' };
|
||||
Char STRbang[] = { '!', '\0' };
|
||||
Char STRcaret[] = { '^', '\0' };
|
||||
Char STRcdpath[] = { 'c', 'd', 'p', 'a', 't', 'h', '\0' };
|
||||
Char STRcent2[] = { '%', '%', '\0' };
|
||||
Char STRcenthash[] = { '%', '#', '\0' };
|
||||
Char STRcentplus[] = { '%', '+', '\0' };
|
||||
Char STRcentminus[] = { '%', '-', '\0' };
|
||||
Char STRchase_symlinks[] = { 'c', 'h', 'a', 's', 'e', '_', 's', 'y', 'm', 'l',
|
||||
'i', 'n', 'k', 's', '\0' };
|
||||
Char STRchild[] = { 'c', 'h', 'i', 'l', 'd', '\0' };
|
||||
Char STRcolon[] = { ':', '\0' };
|
||||
Char STRcwd[] = { 'c', 'w', 'd', '\0' };
|
||||
Char STRdefault[] = { 'd', 'e', 'f', 'a', 'u', 'l', 't', '\0' };
|
||||
Char STRdot[] = { '.', '\0' };
|
||||
Char STRdotdotsl[] = { '.', '.', '/', '\0' };
|
||||
Char STRdotsl[] = { '.', '/', '\0' };
|
||||
Char STRecho[] = { 'e', 'c', 'h', 'o', '\0' };
|
||||
Char STRedit[] = { 'e', 'd', 'i', 't', '\0' };
|
||||
Char STRequal[] = { '=', '\0' };
|
||||
Char STRfakecom[] = { '{', ' ', '.', '.', '.', ' ', '}', '\0' };
|
||||
Char STRfakecom1[] = { '`', ' ', '.', '.', '.', ' ', '`', '\0' };
|
||||
Char STRfignore[] = { 'f', 'i', 'g', 'n', 'o', 'r', 'e', '\0' };
|
||||
#ifdef FILEC
|
||||
Char STRfilec[] = { 'f', 'i', 'l', 'e', 'c', '\0' };
|
||||
#endif /* FILEC */
|
||||
Char STRhistchars[] = { 'h', 'i', 's', 't', 'c', 'h', 'a', 'r', 's', '\0' };
|
||||
Char STRtildothist[] = { '~', '/', '.', 'h', 'i', 's', 't', 'o', 'r',
|
||||
'y', '\0' };
|
||||
Char STRhistfile[] = { 'h', 'i', 's', 't', 'f', 'i', 'l', 'e', '\0' };
|
||||
Char STRhistory[] = { 'h', 'i', 's', 't', 'o', 'r', 'y', '\0' };
|
||||
Char STRhome[] = { 'h', 'o', 'm', 'e', '\0' };
|
||||
Char STRignore_symlinks[] = { 'i', 'g', 'n', 'o', 'r', 'e', '_', 's', 'y', 'm',
|
||||
'l', 'i', 'n', 'k', 's', '\0' };
|
||||
Char STRignoreeof[] = { 'i', 'g', 'n', 'o', 'r', 'e', 'e', 'o', 'f', '\0' };
|
||||
Char STRjobs[] = { 'j', 'o', 'b', 's', '\0' };
|
||||
Char STRlistjobs[] = { 'l', 'i', 's', 't', 'j', 'o', 'b', 's', '\0' };
|
||||
Char STRlogout[] = { 'l', 'o', 'g', 'o', 'u', 't', '\0' };
|
||||
Char STRlong[] = { 'l', 'o', 'n', 'g', '\0' };
|
||||
Char STRmail[] = { 'm', 'a', 'i', 'l', '\0' };
|
||||
Char STRmh[] = { '-', 'h', '\0' };
|
||||
Char STRminus[] = { '-', '\0' };
|
||||
Char STRml[] = { '-', 'l', '\0' };
|
||||
Char STRmn[] = { '-', 'n', '\0' };
|
||||
Char STRmquestion[] = { '?' | QUOTE, ' ', '\0' };
|
||||
Char STRnice[] = { 'n', 'i', 'c', 'e', '\0' };
|
||||
Char STRnoambiguous[] = { 'n', 'o', 'a', 'm', 'b', 'i', 'g', 'u', 'o', 'u',
|
||||
's', '\0' };
|
||||
Char STRnobeep[] = { 'n', 'o', 'b', 'e', 'e', 'p', '\0' };
|
||||
Char STRnoclobber[] = { 'n', 'o', 'c', 'l', 'o', 'b', 'b', 'e', 'r', '\0' };
|
||||
Char STRnoglob[] = { 'n', 'o', 'g', 'l', 'o', 'b', '\0' };
|
||||
Char STRnohup[] = { 'n', 'o', 'h', 'u', 'p', '\0' };
|
||||
Char STRnonomatch[] = { 'n', 'o', 'n', 'o', 'm', 'a', 't', 'c', 'h', '\0' };
|
||||
Char STRnormal[] = { 'n', 'o', 'r', 'm', 'a', 'l', '\0' };
|
||||
Char STRnotify[] = { 'n', 'o', 't', 'i', 'f', 'y', '\0' };
|
||||
Char STRor[] = { '|', '\0' };
|
||||
Char STRor2[] = { '|', '|', '\0' };
|
||||
Char STRpath[] = { 'p', 'a', 't', 'h', '\0' };
|
||||
Char STRprintexitvalue[] = { 'p', 'r', 'i', 'n', 't', 'e', 'x', 'i', 't', 'v',
|
||||
'a', 'l', 'u', 'e', '\0' };
|
||||
Char STRprompt[] = { 'p', 'r', 'o', 'm', 'p', 't', '\0' };
|
||||
Char STRprompt2[] = { 'p', 'r', 'o', 'm', 'p', 't', '2', '\0' };
|
||||
Char STRpushdsilent[] = { 'p', 'u', 's', 'h', 'd', 's', 'i', 'l', 'e', 'n',
|
||||
't', '\0' };
|
||||
Char STRret[] = { '\n', '\0' };
|
||||
Char STRsavehist[] = { 's', 'a', 'v', 'e', 'h', 'i', 's', 't', '\0' };
|
||||
Char STRsemisp[] = { ';', ' ', '\0' };
|
||||
Char STRshell[] = { 's', 'h', 'e', 'l', 'l', '\0' };
|
||||
Char STRslash[] = { '/', '\0' };
|
||||
Char STRsldotcshrc[] = { '/', '.', 'c', 's', 'h', 'r', 'c', '\0' };
|
||||
Char STRsldotlogin[] = { '/', '.', 'l', 'o', 'g', 'i', 'n', '\0' };
|
||||
Char STRsldthist[] = { '/', '.', 'h', 'i', 's', 't', 'o', 'r', 'y', '\0' };
|
||||
Char STRsldtlogout[] = { '/', '.', 'l', 'o', 'g', 'o', 'u', 't', '\0' };
|
||||
Char STRsource[] = { 's', 'o', 'u', 'r', 'c', 'e', '\0' };
|
||||
Char STRsp3dots[] = { ' ', '.', '.', '.', '\0' };
|
||||
Char STRspLarrow2sp[] = { ' ', '<', '<', ' ', '\0' };
|
||||
Char STRspLarrowsp[] = { ' ', '<', ' ', '\0' };
|
||||
Char STRspRarrow[] = { ' ', '>', '\0' };
|
||||
Char STRspRarrow2[] = { ' ', '>', '>', '\0' };
|
||||
Char STRRparen[] = { ')', '\0' };
|
||||
Char STRspace[] = { ' ', '\0' };
|
||||
Char STRspand2sp[] = { ' ', '&', '&', ' ', '\0' };
|
||||
Char STRspor2sp[] = { ' ', '|', '|', ' ', '\0' };
|
||||
Char STRsporsp[] = { ' ', '|', ' ', '\0' };
|
||||
Char STRstar[] = { '*', '\0' };
|
||||
Char STRstatus[] = { 's', 't', 'a', 't', 'u', 's', '\0' };
|
||||
Char STRsymcent[] = { '%', ' ', '\0' };
|
||||
Char STRsymhash[] = { '#', ' ', '\0' };
|
||||
Char STRterm[] = { 't', 'e', 'r', 'm', '\0' };
|
||||
Char STRthen[] = { 't', 'h', 'e', 'n', '\0' };
|
||||
Char STRtilde[] = { '~', '\0' };
|
||||
Char STRtime[] = { 't', 'i', 'm', 'e', '\0' };
|
||||
Char STRtmpsh[] = { '/', 't', 'm', 'p', '/', 's', 'h', '\0' };
|
||||
Char STRunalias[] = { 'u', 'n', 'a', 'l', 'i', 'a', 's', '\0' };
|
||||
Char STRuser[] = { 'u', 's', 'e', 'r', '\0' };
|
||||
Char STRverbose[] = { 'v', 'e', 'r', 'b', 'o', 's', 'e', '\0' };
|
||||
Char STRwordchars[] = { 'w', 'o', 'r', 'd', 'c', 'h', 'a', 'r', 's', '\0' };
|
||||
2293
bin/csh/csh.1
Normal file
2293
bin/csh/csh.1
Normal file
File diff suppressed because it is too large
Load Diff
1401
bin/csh/csh.c
Normal file
1401
bin/csh/csh.c
Normal file
File diff suppressed because it is too large
Load Diff
559
bin/csh/csh.h
Normal file
559
bin/csh/csh.h
Normal file
@@ -0,0 +1,559 @@
|
||||
/* $NetBSD: csh.h,v 1.26 2013/07/16 17:47:43 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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.
|
||||
*
|
||||
* @(#)csh.h 8.1 (Berkeley) 5/31/93
|
||||
*/
|
||||
|
||||
#ifndef _CSH_H_
|
||||
#define _CSH_H_
|
||||
|
||||
/*
|
||||
* Fundamental definitions which may vary from system to system.
|
||||
*
|
||||
* BUFSIZE The i/o buffering size; also limits word size
|
||||
* MAILINTVL How often to mailcheck; more often is more expensive
|
||||
*/
|
||||
#ifndef BUFSIZE
|
||||
#define BUFSIZE 4096 /* default buffer size */
|
||||
#endif /* BUFSIZE */
|
||||
|
||||
#define FORKSLEEP 10 /* delay loop on non-interactive fork failure */
|
||||
#define MAILINTVL 600 /* 10 minutes */
|
||||
|
||||
/*
|
||||
* The shell moves std in/out/diag and the old std input away from units
|
||||
* 0, 1, and 2 so that it is easy to set up these standards for invoked
|
||||
* commands.
|
||||
*/
|
||||
#define FSHTTY 15 /* /dev/tty when manip pgrps */
|
||||
#define FSHIN 16 /* Preferred desc for shell input */
|
||||
#define FSHOUT 17 /* ... shell output */
|
||||
#define FSHERR 18 /* ... shell diagnostics */
|
||||
#define FOLDSTD 19 /* ... old std input */
|
||||
|
||||
#ifdef PROF
|
||||
#define xexit(n) done(n)
|
||||
#endif
|
||||
|
||||
#ifdef SHORT_STRINGS
|
||||
typedef short Char;
|
||||
|
||||
#define SAVE(a) (Strsave(str2short(a)))
|
||||
#else
|
||||
typedef char Char;
|
||||
|
||||
#define SAVE(a) (strsave(a))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure a variable is not stored in a register by taking its address
|
||||
* This is used where variables might be clobbered by longjmp.
|
||||
*/
|
||||
#define UNREGISTER(a) (void) &a
|
||||
|
||||
typedef void *ioctl_t; /* Third arg of ioctl */
|
||||
|
||||
typedef void *ptr_t;
|
||||
|
||||
#include "const.h"
|
||||
#include "char.h"
|
||||
#include "errnum.h"
|
||||
|
||||
#define xmalloc(i) Malloc(i)
|
||||
#define xrealloc(p, i) Realloc(p, i)
|
||||
#define xcalloc(n, s) Calloc(n, s)
|
||||
#define xfree(p) Free(p)
|
||||
|
||||
#include <stdio.h>
|
||||
FILE *cshin, *cshout, *csherr;
|
||||
|
||||
#define isdir(d) (S_ISDIR(d.st_mode))
|
||||
|
||||
#define eq(a, b) (Strcmp(a, b) == 0)
|
||||
|
||||
/* globone() flags */
|
||||
#define G_ERROR 0 /* default action: error if multiple words */
|
||||
#define G_IGNORE 1 /* ignore the rest of the words */
|
||||
#define G_APPEND 2 /* make a sentence by cat'ing the words */
|
||||
|
||||
/*
|
||||
* Global flags
|
||||
*/
|
||||
int child; /* Child shell ... errors cause exit */
|
||||
int chkstop; /* Warned of stopped jobs... allow exit */
|
||||
int didfds; /* Have setup i/o fd's for child */
|
||||
int doneinp; /* EOF indicator after reset from readc */
|
||||
int exiterr; /* Exit if error or non-zero exit status */
|
||||
int haderr; /* Reset was because of an error */
|
||||
int havhash; /* path hashing is available */
|
||||
int intact; /* We are interactive... therefore prompt */
|
||||
int intty; /* Input is a tty */
|
||||
int justpr; /* Just print because of :p hist mod */
|
||||
int loginsh; /* We are a loginsh -> .login/.logout */
|
||||
int neednote; /* Need to pnotify() */
|
||||
int noexec; /* Don't execute, just syntax check */
|
||||
int pjobs; /* want to print jobs if interrupted */
|
||||
int setintr; /* Set interrupts on/off -> Wait intr... */
|
||||
int timflg; /* Time the next waited for command */
|
||||
|
||||
#ifdef FILEC
|
||||
extern int filec; /* doing filename expansion */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Global i/o info
|
||||
*/
|
||||
Char *arginp; /* Argument input for sh -c and internal `xx` */
|
||||
Char *ffile; /* Name of shell file for $0 */
|
||||
int onelflg; /* 2 -> need line for -t, 1 -> exit on read */
|
||||
|
||||
extern char *seterr; /* Error message from scanner/parser */
|
||||
Char *shtemp; /* Temp name for << shell files in /tmp */
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
struct timespec time0; /* Time at which the shell started */
|
||||
struct rusage ru0;
|
||||
|
||||
/*
|
||||
* Miscellany
|
||||
*/
|
||||
time_t chktim; /* Time mail last checked */
|
||||
Char *doldol; /* Character pid for $$ */
|
||||
pid_t backpid; /* Pid of the last background process */
|
||||
gid_t egid, gid; /* Invokers gid */
|
||||
uid_t euid, uid; /* Invokers uid */
|
||||
int shpgrp; /* Pgrp of shell */
|
||||
int tpgrp; /* Terminal process group */
|
||||
|
||||
/* If tpgrp is -1, leave tty alone! */
|
||||
int opgrp; /* Initial pgrp and tty pgrp */
|
||||
|
||||
|
||||
/*
|
||||
* To be able to redirect i/o for builtins easily, the shell moves the i/o
|
||||
* descriptors it uses away from 0,1,2.
|
||||
* Ideally these should be in units which are closed across exec's
|
||||
* (this saves work) but for version 6, this is not usually possible.
|
||||
* The desired initial values for these descriptors are F{SHIN,...}.
|
||||
*/
|
||||
int SHIN; /* Current shell input (script) */
|
||||
int SHOUT; /* Shell output */
|
||||
int SHERR; /* Diagnostic output... shell errs go here */
|
||||
int OLDSTD; /* Old standard input (def for cmds) */
|
||||
|
||||
/*
|
||||
* Error control
|
||||
*
|
||||
* Errors in scanning and parsing set up an error message to be printed
|
||||
* at the end and complete. Other errors always cause a reset.
|
||||
* Because of source commands and .cshrc we need nested error catches.
|
||||
*/
|
||||
|
||||
#include <setjmp.h>
|
||||
jmp_buf reslab;
|
||||
|
||||
#define setexit() (setjmp(reslab))
|
||||
#define reset() longjmp(reslab, 1)
|
||||
/* Should use structure assignment here */
|
||||
#define getexit(a) (void)memcpy((a), reslab, sizeof reslab)
|
||||
#define resexit(a) (void)memcpy(reslab, (a), sizeof reslab)
|
||||
|
||||
Char *gointr; /* Label for an onintr transfer */
|
||||
|
||||
#include <signal.h>
|
||||
sig_t parintr; /* Parents interrupt catch */
|
||||
sig_t parterm; /* Parents terminate catch */
|
||||
|
||||
/*
|
||||
* Lexical definitions.
|
||||
*
|
||||
* All lexical space is allocated dynamically.
|
||||
* The eighth/sixteenth bit of characters is used to prevent recognition,
|
||||
* and eventually stripped.
|
||||
*/
|
||||
#define META 0x80
|
||||
#define ASCII 0x7f
|
||||
#ifdef SHORT_STRINGS
|
||||
#define CHAR ((Char)0xff)
|
||||
#define QUOTE ((Char)0x8000) /* 16nth char bit used for 'ing */
|
||||
#define TRIM ((Char)0x7fff) /* Mask to strip quote bit */
|
||||
#else
|
||||
#define CHAR ((Char)0x7f)
|
||||
#define QUOTE ((Char)0x80) /* Eighth char bit used for 'ing */
|
||||
#define TRIM ((Char)0x7f) /* Mask to strip quote bit */
|
||||
#endif
|
||||
|
||||
int AsciiOnly; /* If set only 7 bits is expected in characters */
|
||||
|
||||
/*
|
||||
* Each level of input has a buffered input structure.
|
||||
* There are one or more blocks of buffered input for each level,
|
||||
* exactly one if the input is seekable and tell is available.
|
||||
* In other cases, the shell buffers enough blocks to keep all loops
|
||||
* in the buffer.
|
||||
*/
|
||||
struct Bin {
|
||||
off_t Bfseekp; /* Seek pointer */
|
||||
off_t Bfbobp; /* Seekp of beginning of buffers */
|
||||
off_t Bfeobp; /* Seekp of end of buffers */
|
||||
int Bfblocks; /* Number of buffer blocks */
|
||||
Char **Bfbuf; /* The array of buffer blocks */
|
||||
} B;
|
||||
|
||||
/*
|
||||
* This structure allows us to seek inside aliases
|
||||
*/
|
||||
struct Ain {
|
||||
int type;
|
||||
#define I_SEEK -1 /* Invalid seek */
|
||||
#define A_SEEK 0 /* Alias seek */
|
||||
#define F_SEEK 1 /* File seek */
|
||||
#define E_SEEK 2 /* Eval seek */
|
||||
union {
|
||||
off_t _f_seek;
|
||||
Char* _c_seek;
|
||||
} fc;
|
||||
#define f_seek fc._f_seek
|
||||
#define c_seek fc._c_seek
|
||||
Char **a_seek;
|
||||
} ;
|
||||
extern int aret; /* What was the last character returned */
|
||||
#define SEEKEQ(a, b) ((a)->type == (b)->type && \
|
||||
(a)->f_seek == (b)->f_seek && \
|
||||
(a)->a_seek == (b)->a_seek)
|
||||
|
||||
#define fseekp B.Bfseekp
|
||||
#define fbobp B.Bfbobp
|
||||
#define feobp B.Bfeobp
|
||||
#define fblocks B.Bfblocks
|
||||
#define fbuf B.Bfbuf
|
||||
|
||||
/*
|
||||
* The shell finds commands in loops by reseeking the input
|
||||
* For whiles, in particular, it reseeks to the beginning of the
|
||||
* line the while was on; hence the while placement restrictions.
|
||||
*/
|
||||
struct Ain lineloc;
|
||||
|
||||
int cantell; /* Is current source tellable ? */
|
||||
|
||||
/*
|
||||
* Input lines are parsed into doubly linked circular
|
||||
* lists of words of the following form.
|
||||
*/
|
||||
struct wordent {
|
||||
Char *word;
|
||||
struct wordent *prev;
|
||||
struct wordent *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* During word building, both in the initial lexical phase and
|
||||
* when expanding $ variable substitutions, expansion by `!' and `$'
|
||||
* must be inhibited when reading ahead in routines which are themselves
|
||||
* processing `!' and `$' expansion or after characters such as `\' or in
|
||||
* quotations. The following flags are passed to the getC routines
|
||||
* telling them which of these substitutions are appropriate for the
|
||||
* next character to be returned.
|
||||
*/
|
||||
#define DODOL 1
|
||||
#define DOEXCL 2
|
||||
#define DOALL DODOL|DOEXCL
|
||||
|
||||
/*
|
||||
* Labuf implements a general buffer for lookahead during lexical operations.
|
||||
* Text which is to be placed in the input stream can be stuck here.
|
||||
* We stick parsed ahead $ constructs during initial input,
|
||||
* process id's from `$$', and modified variable values (from qualifiers
|
||||
* during expansion in sh.dol.c) here.
|
||||
*/
|
||||
Char *lap;
|
||||
|
||||
/*
|
||||
* Parser structure
|
||||
*
|
||||
* Each command is parsed to a tree of command structures and
|
||||
* flags are set bottom up during this process, to be propagated down
|
||||
* as needed during the semantics/execution pass (sh.sem.c).
|
||||
*/
|
||||
struct command {
|
||||
int t_dtyp; /* Type of node */
|
||||
#define NODE_COMMAND 1 /* t_dcom <t_dlef >t_drit */
|
||||
#define NODE_PAREN 2 /* ( t_dspr ) <t_dlef >t_drit */
|
||||
#define NODE_PIPE 3 /* t_dlef | t_drit */
|
||||
#define NODE_LIST 4 /* t_dlef ; t_drit */
|
||||
#define NODE_OR 5 /* t_dlef || t_drit */
|
||||
#define NODE_AND 6 /* t_dlef && t_drit */
|
||||
int t_dflg; /* Flags, e.g. F_AMPERSAND|... */
|
||||
#define F_SAVE (F_NICE|F_TIME|F_NOHUP) /* save these when re-doing */
|
||||
|
||||
#define F_AMPERSAND (1<<0) /* executes in background */
|
||||
#define F_APPEND (1<<1) /* output is redirected >> */
|
||||
#define F_PIPEIN (1<<2) /* input is a pipe */
|
||||
#define F_PIPEOUT (1<<3) /* output is a pipe */
|
||||
#define F_NOFORK (1<<4) /* don't fork, last ()ized cmd */
|
||||
#define F_NOINTERRUPT (1<<5) /* should be immune from intr's */
|
||||
/* spare */
|
||||
#define F_STDERR (1<<7) /* redirect unit 2 with unit 1 */
|
||||
#define F_OVERWRITE (1<<8) /* output was ! */
|
||||
#define F_READ (1<<9) /* input redirection is << */
|
||||
#define F_REPEAT (1<<10) /* reexec aft if, repeat,... */
|
||||
#define F_NICE (1<<11) /* t_nice is meaningful */
|
||||
#define F_NOHUP (1<<12) /* nohup this command */
|
||||
#define F_TIME (1<<13) /* time this command */
|
||||
union {
|
||||
Char *T_dlef; /* Input redirect word */
|
||||
struct command *T_dcar; /* Left part of list/pipe */
|
||||
} L;
|
||||
union {
|
||||
Char *T_drit; /* Output redirect word */
|
||||
struct command *T_dcdr; /* Right part of list/pipe */
|
||||
} R;
|
||||
#define t_dlef L.T_dlef
|
||||
#define t_dcar L.T_dcar
|
||||
#define t_drit R.T_drit
|
||||
#define t_dcdr R.T_dcdr
|
||||
Char **t_dcom; /* Command/argument vector */
|
||||
struct command *t_dspr; /* Pointer to ()'d subtree */
|
||||
int t_nice;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* These are declared here because they want to be
|
||||
* initialized in sh.init.c (to allow them to be made readonly)
|
||||
*/
|
||||
|
||||
extern struct biltins {
|
||||
const char *bname;
|
||||
void (*bfunct)(Char **, struct command *);
|
||||
short minargs, maxargs;
|
||||
} bfunc[];
|
||||
|
||||
extern int nbfunc;
|
||||
extern int nsrchn;
|
||||
|
||||
extern struct srch {
|
||||
const char *s_name;
|
||||
short s_value;
|
||||
} srchn[];
|
||||
|
||||
/*
|
||||
* The keywords for the parser
|
||||
*/
|
||||
#define T_BREAK 0
|
||||
#define T_BRKSW 1
|
||||
#define T_CASE 2
|
||||
#define T_DEFAULT 3
|
||||
#define T_ELSE 4
|
||||
#define T_END 5
|
||||
#define T_ENDIF 6
|
||||
#define T_ENDSW 7
|
||||
#define T_EXIT 8
|
||||
#define T_FOREACH 9
|
||||
#define T_GOTO 10
|
||||
#define T_IF 11
|
||||
#define T_LABEL 12
|
||||
#define T_LET 13
|
||||
#define T_SET 14
|
||||
#define T_SWITCH 15
|
||||
#define T_TEST 16
|
||||
#define T_THEN 17
|
||||
#define T_WHILE 18
|
||||
|
||||
/*
|
||||
* Structure defining the existing while/foreach loops at this
|
||||
* source level. Loops are implemented by seeking back in the
|
||||
* input. For foreach (fe), the word list is attached here.
|
||||
*/
|
||||
struct whyle {
|
||||
struct Ain w_start; /* Point to restart loop */
|
||||
struct Ain w_end; /* End of loop (0 if unknown) */
|
||||
Char **w_fe, **w_fe0; /* Current/initial wordlist for fe */
|
||||
Char *w_fename; /* Name for fe */
|
||||
struct whyle *w_next; /* Next (more outer) loop */
|
||||
} *whyles;
|
||||
|
||||
/*
|
||||
* Variable structure
|
||||
*
|
||||
* Aliases and variables are stored in AVL balanced binary trees.
|
||||
*/
|
||||
struct varent {
|
||||
Char **vec; /* Array of words which is the value */
|
||||
Char *v_name; /* Name of variable/alias */
|
||||
struct varent *v_link[3]; /* The links, see below */
|
||||
int v_bal; /* Balance factor */
|
||||
} shvhed, aliases;
|
||||
|
||||
#define v_left v_link[0]
|
||||
#define v_right v_link[1]
|
||||
#define v_parent v_link[2]
|
||||
|
||||
#define adrof(v) adrof1(v, &shvhed)
|
||||
#define value(v) value1(v, &shvhed)
|
||||
|
||||
/*
|
||||
* The following are for interfacing redo substitution in
|
||||
* aliases to the lexical routines.
|
||||
*/
|
||||
struct wordent *alhistp; /* Argument list (first) */
|
||||
struct wordent *alhistt; /* Node after last in arg list */
|
||||
extern Char **alvec, *alvecp; /* The (remnants of) alias vector */
|
||||
|
||||
/*
|
||||
* Filename/command name expansion variables
|
||||
*/
|
||||
int gflag; /* After tglob -> is globbing needed? */
|
||||
|
||||
#define MAXVARLEN 30 /* Maximum number of char in a variable name */
|
||||
|
||||
/*
|
||||
* Variables for filename expansion
|
||||
*/
|
||||
extern long gargc; /* Number args in gargv */
|
||||
extern Char **gargv; /* Pointer to the (stack) arglist */
|
||||
|
||||
/*
|
||||
* Variables for command expansion.
|
||||
*/
|
||||
extern Char **pargv; /* Pointer to the argv list space */
|
||||
extern long pargc; /* Count of arguments in pargv */
|
||||
long pnleft; /* Number of chars left in pargs */
|
||||
Char *pargs; /* Pointer to start current word */
|
||||
Char *pargcp; /* Current index into pargs */
|
||||
|
||||
/*
|
||||
* History list
|
||||
*
|
||||
* Each history list entry contains an embedded wordlist
|
||||
* from the scanner, a number for the event, and a reference count
|
||||
* to aid in discarding old entries.
|
||||
*
|
||||
* Essentially "invisible" entries are put on the history list
|
||||
* when history substitution includes modifiers, and thrown away
|
||||
* at the next discarding since their event numbers are very negative.
|
||||
*/
|
||||
struct Hist {
|
||||
struct wordent Hlex;
|
||||
int Hnum;
|
||||
int Href;
|
||||
struct Hist *Hnext;
|
||||
} Histlist;
|
||||
|
||||
struct wordent paraml; /* Current lexical word list */
|
||||
int eventno; /* Next events number */
|
||||
int lastev; /* Last event reference (default) */
|
||||
|
||||
Char HIST; /* history invocation character */
|
||||
Char HISTSUB; /* auto-substitute character */
|
||||
|
||||
/*
|
||||
* strings.h:
|
||||
*/
|
||||
#ifndef SHORT_STRINGS
|
||||
#define Strchr(a, b) strchr(a, b)
|
||||
#define Strrchr(a, b) strrchr(a, b)
|
||||
#define Strcat(a, b) strcat(a, b)
|
||||
#define Strncat(a, b, c) strncat(a, b, c)
|
||||
#define Strcpy(a, b) strcpy(a, b)
|
||||
#define Strncpy(a, b, c) strncpy(a, b, c)
|
||||
#define Strlen(a) strlen(a)
|
||||
#define Strcmp(a, b) strcmp(a, b)
|
||||
#define Strncmp(a, b, c) strncmp(a, b, c)
|
||||
|
||||
#define Strspl(a, b) strspl(a, b)
|
||||
#define Strsave(a) strsave(a)
|
||||
#define Strend(a) strend(a)
|
||||
#define Strstr(a, b) strstr(a, b)
|
||||
|
||||
#define str2short(a) (a)
|
||||
#define blk2short(a) saveblk(a)
|
||||
#define short2blk(a) saveblk(a)
|
||||
#define short2str(a) strip(a)
|
||||
#else
|
||||
#define Strchr(a, b) s_strchr(a, b)
|
||||
#define Strrchr(a, b) s_strrchr(a, b)
|
||||
#define Strcat(a, b) s_strcat(a, b)
|
||||
#define Strncat(a, b, c) s_strncat(a, b, c)
|
||||
#define Strcpy(a, b) s_strcpy(a, b)
|
||||
#define Strncpy(a, b, c) s_strncpy(a, b, c)
|
||||
#define Strlen(a) s_strlen(a)
|
||||
#define Strcmp(a, b) s_strcmp(a, b)
|
||||
#define Strncmp(a, b, c) s_strncmp(a, b, c)
|
||||
|
||||
#define Strspl(a, b) s_strspl(a, b)
|
||||
#define Strsave(a) s_strsave(a)
|
||||
#define Strend(a) s_strend(a)
|
||||
#define Strstr(a, b) s_strstr(a, b)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* setname is a macro to save space (see sh.err.c)
|
||||
*/
|
||||
const char *bname;
|
||||
|
||||
#define setname(a) (bname = (a))
|
||||
|
||||
Char *Vsav;
|
||||
Char *Vdp;
|
||||
Char *Vexpath;
|
||||
char **Vt;
|
||||
|
||||
Char **evalvec;
|
||||
Char *evalp;
|
||||
|
||||
/* word_chars is set by default to WORD_CHARS but can be overridden by
|
||||
the worchars variable--if unset, reverts to WORD_CHARS */
|
||||
|
||||
Char *word_chars;
|
||||
|
||||
#define WORD_CHARS "*?_-.[]~=" /* default chars besides alnums in words */
|
||||
|
||||
Char *STR_SHELLPATH;
|
||||
|
||||
#include <paths.h>
|
||||
#ifdef _PATH_BSHELL
|
||||
Char *STR_BSHELL;
|
||||
#endif
|
||||
Char *STR_WORD_CHARS;
|
||||
Char **STR_environ;
|
||||
|
||||
#ifdef EDIT
|
||||
#include <histedit.h>
|
||||
EditLine *el;
|
||||
History *hi;
|
||||
#endif
|
||||
int editing;
|
||||
|
||||
#endif /* !_CSH_H_ */
|
||||
901
bin/csh/dir.c
Normal file
901
bin/csh/dir.c
Normal file
@@ -0,0 +1,901 @@
|
||||
/* $NetBSD: dir.c,v 1.30 2013/07/16 17:47:43 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)dir.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: dir.c,v 1.30 2013/07/16 17:47:43 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "csh.h"
|
||||
#include "dir.h"
|
||||
#include "extern.h"
|
||||
|
||||
/* Directory management. */
|
||||
|
||||
static struct directory *dfind(Char *);
|
||||
static Char *dfollow(Char *);
|
||||
static void printdirs(void);
|
||||
static Char *dgoto(Char *);
|
||||
static void skipargs(Char ***, const char *);
|
||||
static void dnewcwd(struct directory *);
|
||||
static void dset(Char *);
|
||||
|
||||
struct directory dhead; /* "head" of loop */
|
||||
int printd; /* force name to be printed */
|
||||
|
||||
static int dirflag = 0;
|
||||
|
||||
/*
|
||||
* dinit - initialize current working directory
|
||||
*/
|
||||
void
|
||||
dinit(Char *hp)
|
||||
{
|
||||
static const char emsg[] = "csh: Trying to start from \"%s\"\n";
|
||||
char path[MAXPATHLEN];
|
||||
struct directory *dp;
|
||||
const char *ecp;
|
||||
Char *cp;
|
||||
|
||||
/* Don't believe the login shell home, because it may be a symlink */
|
||||
ecp = getcwd(path, MAXPATHLEN);
|
||||
if (ecp == NULL || *ecp == '\0') {
|
||||
(void)fprintf(csherr, "csh: %s\n", strerror(errno));
|
||||
if (hp && *hp) {
|
||||
ecp = short2str(hp);
|
||||
if (chdir(ecp) == -1)
|
||||
cp = NULL;
|
||||
else
|
||||
cp = Strsave(hp);
|
||||
(void)fprintf(csherr, emsg, vis_str(hp));
|
||||
}
|
||||
else
|
||||
cp = NULL;
|
||||
if (cp == NULL) {
|
||||
(void)fprintf(csherr, emsg, "/");
|
||||
if (chdir("/") == -1) {
|
||||
/* I am not even try to print an error message! */
|
||||
xexit(1);
|
||||
}
|
||||
cp = SAVE("/");
|
||||
}
|
||||
}
|
||||
else {
|
||||
struct stat swd, shp;
|
||||
|
||||
/*
|
||||
* See if $HOME is the working directory we got and use that
|
||||
*/
|
||||
if (hp && *hp &&
|
||||
stat(ecp, &swd) != -1 && stat(short2str(hp), &shp) != -1 &&
|
||||
swd.st_dev == shp.st_dev && swd.st_ino == shp.st_ino)
|
||||
cp = Strsave(hp);
|
||||
else {
|
||||
const char *cwd;
|
||||
|
||||
/*
|
||||
* use PWD if we have it (for subshells)
|
||||
*/
|
||||
if ((cwd = getenv("PWD")) != NULL) {
|
||||
if (stat(cwd, &shp) != -1 && swd.st_dev == shp.st_dev &&
|
||||
swd.st_ino == shp.st_ino)
|
||||
ecp = cwd;
|
||||
}
|
||||
cp = dcanon(SAVE(ecp), STRNULL);
|
||||
}
|
||||
}
|
||||
|
||||
dp = (struct directory *)xcalloc(1, sizeof(struct directory));
|
||||
dp->di_name = cp;
|
||||
dp->di_count = 0;
|
||||
dhead.di_next = dhead.di_prev = dp;
|
||||
dp->di_next = dp->di_prev = &dhead;
|
||||
printd = 0;
|
||||
dnewcwd(dp);
|
||||
}
|
||||
|
||||
static void
|
||||
dset(Char *dp)
|
||||
{
|
||||
Char **vec;
|
||||
|
||||
/*
|
||||
* Don't call set() directly cause if the directory contains ` or
|
||||
* other junk characters glob will fail.
|
||||
*/
|
||||
|
||||
vec = xmalloc((size_t)(2 * sizeof(Char **)));
|
||||
vec[0] = Strsave(dp);
|
||||
vec[1] = 0;
|
||||
setq(STRcwd, vec, &shvhed);
|
||||
Setenv(STRPWD, dp);
|
||||
}
|
||||
|
||||
#define DIR_LONG 1
|
||||
#define DIR_VERT 2
|
||||
#define DIR_LINE 4
|
||||
|
||||
static void
|
||||
skipargs(Char ***v, const char *str)
|
||||
{
|
||||
Char **n, *s;
|
||||
|
||||
n = *v;
|
||||
dirflag = 0;
|
||||
for (n++; *n != NULL && (*n)[0] == '-'; n++)
|
||||
for (s = &((*n)[1]); *s; s++)
|
||||
switch (*s) {
|
||||
case 'l':
|
||||
dirflag |= DIR_LONG;
|
||||
break;
|
||||
case 'n':
|
||||
dirflag |= DIR_LINE;
|
||||
break;
|
||||
case 'v':
|
||||
dirflag |= DIR_VERT;
|
||||
break;
|
||||
default:
|
||||
stderror(ERR_DIRUS, vis_str(**v), str);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
*v = n;
|
||||
}
|
||||
|
||||
/*
|
||||
* dodirs - list all directories in directory loop
|
||||
*/
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dodirs(Char **v, struct command *t)
|
||||
{
|
||||
skipargs(&v, "");
|
||||
|
||||
if (*v != NULL)
|
||||
stderror(ERR_DIRUS, "dirs", "");
|
||||
printdirs();
|
||||
}
|
||||
|
||||
static void
|
||||
printdirs(void)
|
||||
{
|
||||
struct directory *dp;
|
||||
Char *hp, *s;
|
||||
size_t cur, idx, len;
|
||||
|
||||
hp = value(STRhome);
|
||||
if (*hp == '\0')
|
||||
hp = NULL;
|
||||
dp = dcwd;
|
||||
idx = 0;
|
||||
cur = 0;
|
||||
do {
|
||||
if (dp == &dhead)
|
||||
continue;
|
||||
if (dirflag & DIR_VERT) {
|
||||
(void)fprintf(cshout, "%zu\t", idx++);
|
||||
cur = 0;
|
||||
}
|
||||
if (!(dirflag & DIR_LONG) && hp != NULL && !eq(hp, STRslash) &&
|
||||
(len = Strlen(hp), Strncmp(hp, dp->di_name, len) == 0) &&
|
||||
(dp->di_name[len] == '\0' || dp->di_name[len] == '/'))
|
||||
len = Strlen(s = (dp->di_name + len)) + 2;
|
||||
else
|
||||
len = Strlen(s = dp->di_name) + 1;
|
||||
|
||||
cur += len;
|
||||
if ((dirflag & DIR_LINE) && cur >= 80 - 1 && len < 80) {
|
||||
(void)fprintf(cshout, "\n");
|
||||
cur = len;
|
||||
}
|
||||
(void) fprintf(cshout, "%s%s%c", (s != dp->di_name)? "~" : "",
|
||||
vis_str(s), (dirflag & DIR_VERT) ? '\n' : ' ');
|
||||
} while ((dp = dp->di_prev) != dcwd);
|
||||
if (!(dirflag & DIR_VERT))
|
||||
(void)fprintf(cshout, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
dtildepr(Char *home, Char *dir)
|
||||
{
|
||||
if (!eq(home, STRslash) && prefix(home, dir))
|
||||
(void)fprintf(cshout, "~%s", vis_str(dir + Strlen(home)));
|
||||
else
|
||||
(void)fprintf(cshout, "%s", vis_str(dir));
|
||||
}
|
||||
|
||||
void
|
||||
dtilde(void)
|
||||
{
|
||||
struct directory *d;
|
||||
|
||||
d = dcwd;
|
||||
do {
|
||||
if (d == &dhead)
|
||||
continue;
|
||||
d->di_name = dcanon(d->di_name, STRNULL);
|
||||
} while ((d = d->di_prev) != dcwd);
|
||||
|
||||
dset(dcwd->di_name);
|
||||
}
|
||||
|
||||
|
||||
/* dnormalize():
|
||||
* If the name starts with . or .. then we might need to normalize
|
||||
* it depending on the symbolic link flags
|
||||
*/
|
||||
Char *
|
||||
dnormalize(Char *cp)
|
||||
{
|
||||
#define UC (unsigned char)
|
||||
#define ISDOT(c) (UC(c)[0] == '.' && ((UC(c)[1] == '\0') || (UC(c)[1] == '/')))
|
||||
#define ISDOTDOT(c) (UC(c)[0] == '.' && ISDOT(&((c)[1])))
|
||||
if ((unsigned char) cp[0] == '/')
|
||||
return (Strsave(cp));
|
||||
|
||||
if (adrof(STRignore_symlinks)) {
|
||||
size_t dotdot = 0;
|
||||
Char *dp, *cwd;
|
||||
|
||||
cwd = xmalloc((size_t)((Strlen(dcwd->di_name) + 3) *
|
||||
sizeof(Char)));
|
||||
(void)Strcpy(cwd, dcwd->di_name);
|
||||
|
||||
/*
|
||||
* Ignore . and count ..'s
|
||||
*/
|
||||
while (*cp) {
|
||||
if (ISDOT(cp)) {
|
||||
if (*++cp)
|
||||
cp++;
|
||||
}
|
||||
else if (ISDOTDOT(cp)) {
|
||||
dotdot++;
|
||||
cp += 2;
|
||||
if (*cp)
|
||||
cp++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
while (dotdot > 0) {
|
||||
dp = Strrchr(cwd, '/');
|
||||
if (dp) {
|
||||
*dp = '\0';
|
||||
dotdot--;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (*cp) {
|
||||
cwd[dotdot = Strlen(cwd)] = '/';
|
||||
cwd[dotdot + 1] = '\0';
|
||||
dp = Strspl(cwd, cp);
|
||||
xfree((ptr_t) cwd);
|
||||
return dp;
|
||||
}
|
||||
else {
|
||||
if (!*cwd) {
|
||||
cwd[0] = '/';
|
||||
cwd[1] = '\0';
|
||||
}
|
||||
return cwd;
|
||||
}
|
||||
}
|
||||
return Strsave(cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* dochngd - implement chdir command.
|
||||
*/
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dochngd(Char **v, struct command *t)
|
||||
{
|
||||
struct directory *dp;
|
||||
Char *cp;
|
||||
|
||||
skipargs(&v, " [<dir>]");
|
||||
printd = 0;
|
||||
if (*v == NULL) {
|
||||
if ((cp = value(STRhome)) == NULL || *cp == 0)
|
||||
stderror(ERR_NAME | ERR_NOHOMEDIR);
|
||||
if (chdir(short2str(cp)) < 0)
|
||||
stderror(ERR_NAME | ERR_CANTCHANGE);
|
||||
cp = Strsave(cp);
|
||||
}
|
||||
else if (v[1] != NULL)
|
||||
stderror(ERR_NAME | ERR_TOOMANY);
|
||||
else if ((dp = dfind(*v)) != 0) {
|
||||
char *tmp;
|
||||
|
||||
printd = 1;
|
||||
if (chdir(tmp = short2str(dp->di_name)) < 0)
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
dcwd->di_prev->di_next = dcwd->di_next;
|
||||
dcwd->di_next->di_prev = dcwd->di_prev;
|
||||
dfree(dcwd);
|
||||
dnewcwd(dp);
|
||||
return;
|
||||
}
|
||||
else
|
||||
cp = dfollow(*v);
|
||||
dp = (struct directory *)xcalloc(1, sizeof(struct directory));
|
||||
dp->di_name = cp;
|
||||
dp->di_count = 0;
|
||||
dp->di_next = dcwd->di_next;
|
||||
dp->di_prev = dcwd->di_prev;
|
||||
dp->di_prev->di_next = dp;
|
||||
dp->di_next->di_prev = dp;
|
||||
dfree(dcwd);
|
||||
dnewcwd(dp);
|
||||
}
|
||||
|
||||
static Char *
|
||||
dgoto(Char *cp)
|
||||
{
|
||||
Char *dp;
|
||||
|
||||
if (*cp != '/') {
|
||||
Char *p, *q;
|
||||
size_t cwdlen;
|
||||
|
||||
for (p = dcwd->di_name; *p++;)
|
||||
continue;
|
||||
if ((cwdlen = (size_t)(p - dcwd->di_name - 1)) == 1) /* root */
|
||||
cwdlen = 0;
|
||||
for (p = cp; *p++;)
|
||||
continue;
|
||||
dp = xmalloc((size_t)(cwdlen + (size_t)(p - cp) + 1) * sizeof(Char));
|
||||
for (p = dp, q = dcwd->di_name; (*p++ = *q++) != '\0';)
|
||||
continue;
|
||||
if (cwdlen)
|
||||
p[-1] = '/';
|
||||
else
|
||||
p--; /* don't add a / after root */
|
||||
for (q = cp; (*p++ = *q++) != '\0';)
|
||||
continue;
|
||||
xfree((ptr_t) cp);
|
||||
cp = dp;
|
||||
dp += cwdlen;
|
||||
}
|
||||
else
|
||||
dp = cp;
|
||||
|
||||
cp = dcanon(cp, dp);
|
||||
return cp;
|
||||
}
|
||||
|
||||
/*
|
||||
* dfollow - change to arg directory; fall back on cdpath if not valid
|
||||
*/
|
||||
static Char *
|
||||
dfollow(Char *cp)
|
||||
{
|
||||
char ebuf[MAXPATHLEN];
|
||||
struct varent *c;
|
||||
Char *dp;
|
||||
int serrno;
|
||||
|
||||
cp = globone(cp, G_ERROR);
|
||||
/*
|
||||
* if we are ignoring symlinks, try to fix relatives now.
|
||||
*/
|
||||
dp = dnormalize(cp);
|
||||
if (chdir(short2str(dp)) >= 0) {
|
||||
xfree((ptr_t) cp);
|
||||
return dgoto(dp);
|
||||
}
|
||||
else {
|
||||
xfree((ptr_t) dp);
|
||||
if (chdir(short2str(cp)) >= 0)
|
||||
return dgoto(cp);
|
||||
serrno = errno;
|
||||
}
|
||||
|
||||
if (cp[0] != '/' && !prefix(STRdotsl, cp) && !prefix(STRdotdotsl, cp)
|
||||
&& (c = adrof(STRcdpath))) {
|
||||
Char **cdp;
|
||||
Char *p;
|
||||
Char buf[MAXPATHLEN];
|
||||
|
||||
for (cdp = c->vec; *cdp; cdp++) {
|
||||
for (dp = buf, p = *cdp; (*dp++ = *p++) != '\0';)
|
||||
continue;
|
||||
dp[-1] = '/';
|
||||
for (p = cp; (*dp++ = *p++) != '\0';)
|
||||
continue;
|
||||
if (chdir(short2str(buf)) >= 0) {
|
||||
printd = 1;
|
||||
xfree((ptr_t) cp);
|
||||
cp = Strsave(buf);
|
||||
return dgoto(cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
dp = value(cp);
|
||||
if ((dp[0] == '/' || dp[0] == '.') && chdir(short2str(dp)) >= 0) {
|
||||
xfree((ptr_t) cp);
|
||||
cp = Strsave(dp);
|
||||
printd = 1;
|
||||
return dgoto(cp);
|
||||
}
|
||||
(void)strcpy(ebuf, short2str(cp));
|
||||
xfree((ptr_t) cp);
|
||||
stderror(ERR_SYSTEM, ebuf, strerror(serrno));
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* dopushd - push new directory onto directory stack.
|
||||
* with no arguments exchange top and second.
|
||||
* with numeric argument (+n) bring it to top.
|
||||
*/
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dopushd(Char **v, struct command *t)
|
||||
{
|
||||
struct directory *dp;
|
||||
|
||||
skipargs(&v, " [<dir>|+<n>]");
|
||||
printd = 1;
|
||||
if (*v == NULL) {
|
||||
char *tmp;
|
||||
|
||||
if ((dp = dcwd->di_prev) == &dhead)
|
||||
dp = dhead.di_prev;
|
||||
if (dp == dcwd)
|
||||
stderror(ERR_NAME | ERR_NODIR);
|
||||
if (chdir(tmp = short2str(dp->di_name)) < 0)
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
dp->di_prev->di_next = dp->di_next;
|
||||
dp->di_next->di_prev = dp->di_prev;
|
||||
dp->di_next = dcwd->di_next;
|
||||
dp->di_prev = dcwd;
|
||||
dcwd->di_next->di_prev = dp;
|
||||
dcwd->di_next = dp;
|
||||
}
|
||||
else if (v[1] != NULL)
|
||||
stderror(ERR_NAME | ERR_TOOMANY);
|
||||
else if ((dp = dfind(*v)) != NULL) {
|
||||
char *tmp;
|
||||
|
||||
if (chdir(tmp = short2str(dp->di_name)) < 0)
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
}
|
||||
else {
|
||||
Char *ccp;
|
||||
|
||||
ccp = dfollow(*v);
|
||||
dp = (struct directory *)xcalloc(1, sizeof(struct directory));
|
||||
dp->di_name = ccp;
|
||||
dp->di_count = 0;
|
||||
dp->di_prev = dcwd;
|
||||
dp->di_next = dcwd->di_next;
|
||||
dcwd->di_next = dp;
|
||||
dp->di_next->di_prev = dp;
|
||||
}
|
||||
dnewcwd(dp);
|
||||
}
|
||||
|
||||
/*
|
||||
* dfind - find a directory if specified by numeric (+n) argument
|
||||
*/
|
||||
static struct directory *
|
||||
dfind(Char *cp)
|
||||
{
|
||||
struct directory *dp;
|
||||
Char *ep;
|
||||
int i;
|
||||
|
||||
if (*cp++ != '+')
|
||||
return (0);
|
||||
for (ep = cp; Isdigit(*ep); ep++)
|
||||
continue;
|
||||
if (*ep)
|
||||
return (0);
|
||||
i = getn(cp);
|
||||
if (i <= 0)
|
||||
return (0);
|
||||
for (dp = dcwd; i != 0; i--) {
|
||||
if ((dp = dp->di_prev) == &dhead)
|
||||
dp = dp->di_prev;
|
||||
if (dp == dcwd)
|
||||
stderror(ERR_NAME | ERR_DEEP);
|
||||
}
|
||||
return (dp);
|
||||
}
|
||||
|
||||
/*
|
||||
* dopopd - pop a directory out of the directory stack
|
||||
* with a numeric argument just discard it.
|
||||
*/
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dopopd(Char **v, struct command *t)
|
||||
{
|
||||
struct directory *dp, *p = NULL;
|
||||
|
||||
skipargs(&v, " [+<n>]");
|
||||
printd = 1;
|
||||
if (*v == NULL)
|
||||
dp = dcwd;
|
||||
else if (v[1] != NULL)
|
||||
stderror(ERR_NAME | ERR_TOOMANY);
|
||||
else if ((dp = dfind(*v)) == 0)
|
||||
stderror(ERR_NAME | ERR_BADDIR);
|
||||
if (dp->di_prev == &dhead && dp->di_next == &dhead)
|
||||
stderror(ERR_NAME | ERR_EMPTY);
|
||||
if (dp == dcwd) {
|
||||
char *tmp;
|
||||
|
||||
if ((p = dp->di_prev) == &dhead)
|
||||
p = dhead.di_prev;
|
||||
if (chdir(tmp = short2str(p->di_name)) < 0)
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
}
|
||||
dp->di_prev->di_next = dp->di_next;
|
||||
dp->di_next->di_prev = dp->di_prev;
|
||||
if (dp == dcwd)
|
||||
dnewcwd(p);
|
||||
else {
|
||||
printdirs();
|
||||
}
|
||||
dfree(dp);
|
||||
}
|
||||
|
||||
/*
|
||||
* dfree - free the directory (or keep it if it still has ref count)
|
||||
*/
|
||||
void
|
||||
dfree(struct directory *dp)
|
||||
{
|
||||
|
||||
if (dp->di_count != 0) {
|
||||
dp->di_next = dp->di_prev = 0;
|
||||
}
|
||||
else {
|
||||
xfree((char *) dp->di_name);
|
||||
xfree((ptr_t) dp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dcanon - canonicalize the pathname, removing excess ./ and ../ etc.
|
||||
* we are of course assuming that the file system is standardly
|
||||
* constructed (always have ..'s, directories have links)
|
||||
*/
|
||||
Char *
|
||||
dcanon(Char *cp, Char *p)
|
||||
{
|
||||
Char slink[MAXPATHLEN];
|
||||
char tlink[MAXPATHLEN];
|
||||
Char *newcp, *sp;
|
||||
Char *p1, *p2; /* general purpose */
|
||||
ssize_t cc;
|
||||
size_t len;
|
||||
int slash;
|
||||
|
||||
/*
|
||||
* christos: if the path given does not start with a slash prepend cwd. If
|
||||
* cwd does not start with a path or the result would be too long abort().
|
||||
*/
|
||||
if (*cp != '/') {
|
||||
Char tmpdir[MAXPATHLEN];
|
||||
|
||||
p1 = value(STRcwd);
|
||||
if (p1 == NULL || *p1 != '/')
|
||||
abort();
|
||||
if (Strlen(p1) + Strlen(cp) + 1 >= MAXPATHLEN)
|
||||
abort();
|
||||
(void)Strcpy(tmpdir, p1);
|
||||
(void)Strcat(tmpdir, STRslash);
|
||||
(void)Strcat(tmpdir, cp);
|
||||
xfree((ptr_t) cp);
|
||||
cp = p = Strsave(tmpdir);
|
||||
}
|
||||
|
||||
while (*p) { /* for each component */
|
||||
sp = p; /* save slash address */
|
||||
while (*++p == '/') /* flush extra slashes */
|
||||
continue;
|
||||
if (p != ++sp)
|
||||
for (p1 = sp, p2 = p; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
p = sp; /* save start of component */
|
||||
slash = 0;
|
||||
while (*++p) /* find next slash or end of path */
|
||||
if (*p == '/') {
|
||||
slash = 1;
|
||||
*p = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*sp == '\0') { /* if component is null */
|
||||
if (--sp == cp) /* if path is one char (i.e. /) */
|
||||
break;
|
||||
else
|
||||
*sp = '\0';
|
||||
} else if (sp[0] == '.' && sp[1] == 0) {
|
||||
if (slash) {
|
||||
for (p1 = sp, p2 = p + 1; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
p = --sp;
|
||||
}
|
||||
else if (--sp != cp)
|
||||
*sp = '\0';
|
||||
}
|
||||
else if (sp[0] == '.' && sp[1] == '.' && sp[2] == 0) {
|
||||
/*
|
||||
* We have something like "yyy/xxx/..", where "yyy" can be null or
|
||||
* a path starting at /, and "xxx" is a single component. Before
|
||||
* compressing "xxx/..", we want to expand "yyy/xxx", if it is a
|
||||
* symbolic link.
|
||||
*/
|
||||
*--sp = 0; /* form the pathname for readlink */
|
||||
if (sp != cp && !adrof(STRignore_symlinks) &&
|
||||
(cc = readlink(short2str(cp), tlink,
|
||||
sizeof(tlink) - 1)) >= 0) {
|
||||
tlink[cc] = '\0';
|
||||
(void)Strcpy(slink, str2short(tlink));
|
||||
|
||||
if (slash)
|
||||
*p = '/';
|
||||
/*
|
||||
* Point p to the '/' in "/..", and restore the '/'.
|
||||
*/
|
||||
*(p = sp) = '/';
|
||||
/*
|
||||
* find length of p
|
||||
*/
|
||||
for (p1 = p; *p1++;)
|
||||
continue;
|
||||
if (*slink != '/') {
|
||||
/*
|
||||
* Relative path, expand it between the "yyy/" and the
|
||||
* "/..". First, back sp up to the character past "yyy/".
|
||||
*/
|
||||
while (*--sp != '/')
|
||||
continue;
|
||||
sp++;
|
||||
*sp = 0;
|
||||
/*
|
||||
* New length is "yyy/" + slink + "/.." and rest
|
||||
*/
|
||||
p1 = newcp = xmalloc(
|
||||
(size_t)((sp - cp) + cc + (p1 - p)) * sizeof(Char));
|
||||
/*
|
||||
* Copy new path into newcp
|
||||
*/
|
||||
for (p2 = cp; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
for (p1--, p2 = slink; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
for (p1--, p2 = p; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
/*
|
||||
* Restart canonicalization at expanded "/xxx".
|
||||
*/
|
||||
p = sp - cp - 1 + newcp;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* New length is slink + "/.." and rest
|
||||
*/
|
||||
p1 = newcp = xmalloc(
|
||||
(size_t)(cc + (p1 - p)) * sizeof(Char));
|
||||
/*
|
||||
* Copy new path into newcp
|
||||
*/
|
||||
for (p2 = slink; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
for (p1--, p2 = p; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
/*
|
||||
* Restart canonicalization at beginning
|
||||
*/
|
||||
p = newcp;
|
||||
}
|
||||
xfree((ptr_t) cp);
|
||||
cp = newcp;
|
||||
continue; /* canonicalize the link */
|
||||
}
|
||||
*sp = '/';
|
||||
if (sp != cp)
|
||||
while (*--sp != '/')
|
||||
continue;
|
||||
if (slash) {
|
||||
for (p1 = sp + 1, p2 = p + 1; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
p = sp;
|
||||
}
|
||||
else if (cp == sp)
|
||||
*++sp = '\0';
|
||||
else
|
||||
*sp = '\0';
|
||||
}
|
||||
else { /* normal dir name (not . or .. or nothing) */
|
||||
|
||||
if (sp != cp && adrof(STRchase_symlinks) &&
|
||||
!adrof(STRignore_symlinks) &&
|
||||
(cc = readlink(short2str(cp), tlink, sizeof(tlink)-1)) >= 0) {
|
||||
tlink[cc] = '\0';
|
||||
(void)Strcpy(slink, str2short(tlink));
|
||||
|
||||
/*
|
||||
* restore the '/'.
|
||||
*/
|
||||
if (slash)
|
||||
*p = '/';
|
||||
|
||||
/*
|
||||
* point sp to p (rather than backing up).
|
||||
*/
|
||||
sp = p;
|
||||
|
||||
/*
|
||||
* find length of p
|
||||
*/
|
||||
for (p1 = p; *p1++;)
|
||||
continue;
|
||||
if (*slink != '/') {
|
||||
/*
|
||||
* Relative path, expand it between the "yyy/" and the
|
||||
* remainder. First, back sp up to the character past
|
||||
* "yyy/".
|
||||
*/
|
||||
while (*--sp != '/')
|
||||
continue;
|
||||
sp++;
|
||||
*sp = 0;
|
||||
/*
|
||||
* New length is "yyy/" + slink + "/.." and rest
|
||||
*/
|
||||
p1 = newcp = xmalloc(
|
||||
(size_t)((sp - cp) + cc + (p1 - p)) * sizeof(Char));
|
||||
/*
|
||||
* Copy new path into newcp
|
||||
*/
|
||||
for (p2 = cp; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
for (p1--, p2 = slink; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
for (p1--, p2 = p; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
/*
|
||||
* Restart canonicalization at expanded "/xxx".
|
||||
*/
|
||||
p = sp - cp - 1 + newcp;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* New length is slink + the rest
|
||||
*/
|
||||
p1 = newcp = xmalloc(
|
||||
(size_t)(cc + (p1 - p)) * sizeof(Char));
|
||||
/*
|
||||
* Copy new path into newcp
|
||||
*/
|
||||
for (p2 = slink; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
for (p1--, p2 = p; (*p1++ = *p2++) != '\0';)
|
||||
continue;
|
||||
/*
|
||||
* Restart canonicalization at beginning
|
||||
*/
|
||||
p = newcp;
|
||||
}
|
||||
xfree((ptr_t) cp);
|
||||
cp = newcp;
|
||||
continue; /* canonicalize the link */
|
||||
}
|
||||
if (slash)
|
||||
*p = '/';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fix home...
|
||||
*/
|
||||
p1 = value(STRhome);
|
||||
len = Strlen(p1);
|
||||
/*
|
||||
* See if we're not in a subdir of STRhome
|
||||
*/
|
||||
if (p1 && *p1 == '/' &&
|
||||
(Strncmp(p1, cp, len) != 0 || (cp[len] != '/' && cp[len] != '\0'))) {
|
||||
static ino_t home_ino;
|
||||
static dev_t home_dev = NODEV;
|
||||
static Char *home_ptr = NULL;
|
||||
struct stat statbuf;
|
||||
|
||||
/*
|
||||
* Get dev and ino of STRhome
|
||||
*/
|
||||
if (home_ptr != p1 &&
|
||||
stat(short2str(p1), &statbuf) != -1) {
|
||||
home_dev = statbuf.st_dev;
|
||||
home_ino = statbuf.st_ino;
|
||||
home_ptr = p1;
|
||||
}
|
||||
/*
|
||||
* Start comparing dev & ino backwards
|
||||
*/
|
||||
p2 = Strcpy(slink, cp);
|
||||
for (sp = NULL; *p2 && stat(short2str(p2), &statbuf) != -1;) {
|
||||
if (statbuf.st_dev == home_dev &&
|
||||
statbuf.st_ino == home_ino) {
|
||||
sp = (Char *) - 1;
|
||||
break;
|
||||
}
|
||||
if ((sp = Strrchr(p2, '/')) != NULL)
|
||||
*sp = '\0';
|
||||
}
|
||||
/*
|
||||
* See if we found it
|
||||
*/
|
||||
if (*p2 && sp == (Char *) -1) {
|
||||
/*
|
||||
* Use STRhome to make '~' work
|
||||
*/
|
||||
newcp = Strspl(p1, cp + Strlen(p2));
|
||||
xfree((ptr_t) cp);
|
||||
cp = newcp;
|
||||
}
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dnewcwd - make a new directory in the loop the current one
|
||||
*/
|
||||
static void
|
||||
dnewcwd(struct directory *dp)
|
||||
{
|
||||
dcwd = dp;
|
||||
dset(dcwd->di_name);
|
||||
if (printd && !(adrof(STRpushdsilent)))
|
||||
printdirs();
|
||||
}
|
||||
48
bin/csh/dir.h
Normal file
48
bin/csh/dir.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* $NetBSD: dir.h,v 1.8 2003/08/07 09:05:04 agc Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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.
|
||||
*
|
||||
* @(#)dir.h 8.1 (Berkeley) 5/31/93
|
||||
*/
|
||||
|
||||
#ifndef _DIR_H_
|
||||
#define _DIR_H_
|
||||
|
||||
/*
|
||||
* Structure for entries in directory stack.
|
||||
*/
|
||||
struct directory {
|
||||
struct directory *di_next; /* next in loop */
|
||||
struct directory *di_prev; /* prev in loop */
|
||||
unsigned short *di_count; /* refcount of processes */
|
||||
Char *di_name; /* actual name */
|
||||
};
|
||||
struct directory *dcwd; /* the one we are in now */
|
||||
|
||||
#endif /* !_DIR_H_ */
|
||||
968
bin/csh/dol.c
Normal file
968
bin/csh/dol.c
Normal file
@@ -0,0 +1,968 @@
|
||||
/* $NetBSD: dol.c,v 1.29 2013/07/16 17:47:43 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)dol.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: dol.c,v 1.29 2013/07/16 17:47:43 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
/*
|
||||
* These routines perform variable substitution and quoting via ' and ".
|
||||
* To this point these constructs have been preserved in the divided
|
||||
* input words. Here we expand variables and turn quoting via ' and " into
|
||||
* QUOTE bits on characters (which prevent further interpretation).
|
||||
* If the `:q' modifier was applied during history expansion, then
|
||||
* some QUOTEing may have occurred already, so we dont "trim()" here.
|
||||
*/
|
||||
|
||||
static int Dpeekc, Dpeekrd; /* Peeks for DgetC and Dreadc */
|
||||
static Char *Dcp, **Dvp; /* Input vector for Dreadc */
|
||||
|
||||
#define DEOF -1
|
||||
#define unDgetC(c) Dpeekc = c
|
||||
#define QUOTES (_QF|_QB|_ESC) /* \ ' " ` */
|
||||
|
||||
/*
|
||||
* The following variables give the information about the current
|
||||
* $ expansion, recording the current word position, the remaining
|
||||
* words within this expansion, the count of remaining words, and the
|
||||
* information about any : modifier which is being applied.
|
||||
*/
|
||||
#define MAXWLEN (BUFSIZE - 4)
|
||||
#define MAXMOD MAXWLEN /* This cannot overflow */
|
||||
static Char dolmod[MAXMOD]; /* : modifier character */
|
||||
static Char *dolp; /* Remaining chars from this word */
|
||||
static Char **dolnxt; /* Further words */
|
||||
static int dolcnt; /* Count of further words */
|
||||
static int dolnmod; /* Number of modifiers */
|
||||
static int dolmcnt; /* :gx -> 10000, else 1 */
|
||||
static int dolwcnt; /* :wx -> 10000, else 1 */
|
||||
|
||||
static void Dfix2(Char **);
|
||||
static Char *Dpack(Char *, Char *);
|
||||
static int Dword(void);
|
||||
__dead static void dolerror(Char *);
|
||||
static int DgetC(int);
|
||||
static void Dgetdol(void);
|
||||
static void fixDolMod(void);
|
||||
static void setDolp(Char *);
|
||||
static void unDredc(int);
|
||||
static int Dredc(void);
|
||||
static void Dtestq(int);
|
||||
|
||||
|
||||
/*
|
||||
* Fix up the $ expansions and quotations in the
|
||||
* argument list to command t.
|
||||
*/
|
||||
void
|
||||
Dfix(struct command *t)
|
||||
{
|
||||
Char *p, **pp;
|
||||
|
||||
if (noexec)
|
||||
return;
|
||||
/* Note that t_dcom isn't trimmed thus !...:q's aren't lost */
|
||||
for (pp = t->t_dcom; (p = *pp++) != NULL;)
|
||||
for (; *p; p++) {
|
||||
if (cmap(*p, _DOL | QUOTES)) { /* $, \, ', ", ` */
|
||||
Dfix2(t->t_dcom); /* found one */
|
||||
blkfree(t->t_dcom);
|
||||
t->t_dcom = gargv;
|
||||
gargv = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* $ substitute one word, for i/o redirection
|
||||
*/
|
||||
Char *
|
||||
Dfix1(Char *cp)
|
||||
{
|
||||
Char *Dv[2];
|
||||
|
||||
if (noexec)
|
||||
return (0);
|
||||
Dv[0] = cp;
|
||||
Dv[1] = NULL;
|
||||
Dfix2(Dv);
|
||||
if (gargc != 1) {
|
||||
setname(vis_str(cp));
|
||||
stderror(ERR_NAME | ERR_AMBIG);
|
||||
}
|
||||
cp = Strsave(gargv[0]);
|
||||
blkfree(gargv), gargv = 0;
|
||||
return (cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Subroutine to do actual fixing after state initialization.
|
||||
*/
|
||||
static void
|
||||
Dfix2(Char **v)
|
||||
{
|
||||
ginit(); /* Initialize glob's area pointers */
|
||||
Dvp = v;
|
||||
Dcp = STRNULL; /* Setup input vector for Dreadc */
|
||||
unDgetC(0);
|
||||
unDredc(0); /* Clear out any old peeks (at error) */
|
||||
dolp = 0;
|
||||
dolcnt = 0; /* Clear out residual $ expands (...) */
|
||||
while (Dword())
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pack up more characters in this word
|
||||
*/
|
||||
static Char *
|
||||
Dpack(Char *wbuf, Char *wp)
|
||||
{
|
||||
int c;
|
||||
ptrdiff_t i;
|
||||
|
||||
i = MAXWLEN - (wp - wbuf);
|
||||
for (;;) {
|
||||
c = DgetC(DODOL);
|
||||
if (c == '\\') {
|
||||
c = DgetC(0);
|
||||
if (c == DEOF) {
|
||||
unDredc(c);
|
||||
*wp = 0;
|
||||
Gcat(STRNULL, wbuf);
|
||||
return (NULL);
|
||||
}
|
||||
if (c == '\n')
|
||||
c = ' ';
|
||||
else
|
||||
c |= QUOTE;
|
||||
}
|
||||
if (c == DEOF) {
|
||||
unDredc(c);
|
||||
*wp = 0;
|
||||
Gcat(STRNULL, wbuf);
|
||||
return (NULL);
|
||||
}
|
||||
if (cmap(c, _SP | _NL | _QF | _QB)) { /* sp \t\n'"` */
|
||||
unDgetC(c);
|
||||
if (cmap(c, QUOTES))
|
||||
return (wp);
|
||||
*wp++ = 0;
|
||||
Gcat(STRNULL, wbuf);
|
||||
return (NULL);
|
||||
}
|
||||
if (--i <= 0)
|
||||
stderror(ERR_WTOOLONG);
|
||||
*wp++ = (Char)c;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a word. This routine is analogous to the routine
|
||||
* word() in sh.lex.c for the main lexical input. One difference
|
||||
* here is that we don't get a newline to terminate our expansion.
|
||||
* Rather, DgetC will return a DEOF when we hit the end-of-input.
|
||||
*/
|
||||
static int
|
||||
Dword(void)
|
||||
{
|
||||
Char wbuf[BUFSIZE], *wp;
|
||||
int c, c1;
|
||||
ptrdiff_t i;
|
||||
int dolflg, done, sofar;
|
||||
|
||||
done = 0;
|
||||
i = MAXWLEN;
|
||||
sofar = 0;
|
||||
wp = wbuf;
|
||||
|
||||
while (!done) {
|
||||
done = 1;
|
||||
c = DgetC(DODOL);
|
||||
switch (c) {
|
||||
case DEOF:
|
||||
if (sofar == 0)
|
||||
return (0);
|
||||
/* finish this word and catch the code above the next time */
|
||||
unDredc(c);
|
||||
/* FALLTHROUGH */
|
||||
case '\n':
|
||||
*wp = 0;
|
||||
Gcat(STRNULL, wbuf);
|
||||
return (1);
|
||||
case ' ':
|
||||
case '\t':
|
||||
done = 0;
|
||||
break;
|
||||
case '`':
|
||||
/* We preserve ` quotations which are done yet later */
|
||||
*wp++ = (Char)c, --i;
|
||||
/* FALLTHROUGH */
|
||||
case '\'':
|
||||
case '"':
|
||||
/*
|
||||
* Note that DgetC never returns a QUOTES character from an
|
||||
* expansion, so only true input quotes will get us here or out.
|
||||
*/
|
||||
c1 = c;
|
||||
dolflg = c1 == '"' ? DODOL : 0;
|
||||
for (;;) {
|
||||
c = DgetC(dolflg);
|
||||
if (c == c1)
|
||||
break;
|
||||
if (c == '\n' || c == DEOF)
|
||||
stderror(ERR_UNMATCHED, c1);
|
||||
if ((c & (QUOTE | TRIM)) == ('\n' | QUOTE))
|
||||
--wp, ++i;
|
||||
if (--i <= 0)
|
||||
stderror(ERR_WTOOLONG);
|
||||
switch (c1) {
|
||||
case '"':
|
||||
/*
|
||||
* Leave any `s alone for later. Other chars are all
|
||||
* quoted, thus `...` can tell it was within "...".
|
||||
*/
|
||||
*wp++ = (Char)(c == '`' ? '`' : (c | QUOTE));
|
||||
break;
|
||||
case '\'':
|
||||
/* Prevent all further interpretation */
|
||||
*wp++ = (Char)(c | QUOTE);
|
||||
break;
|
||||
case '`':
|
||||
/* Leave all text alone for later */
|
||||
*wp++ = (Char)c;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c1 == '`')
|
||||
*wp++ = '`' /* i--; eliminated */;
|
||||
sofar = 1;
|
||||
if ((wp = Dpack(wbuf, wp)) == NULL)
|
||||
return (1);
|
||||
else {
|
||||
i = MAXWLEN - (wp - wbuf);
|
||||
done = 0;
|
||||
}
|
||||
break;
|
||||
case '\\':
|
||||
c = DgetC(0); /* No $ subst! */
|
||||
if (c == '\n' || c == DEOF) {
|
||||
done = 0;
|
||||
break;
|
||||
}
|
||||
c |= QUOTE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (done) {
|
||||
unDgetC(c);
|
||||
sofar = 1;
|
||||
if ((wp = Dpack(wbuf, wp)) == NULL)
|
||||
return (1);
|
||||
else {
|
||||
i = MAXWLEN - (wp - wbuf);
|
||||
done = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Really NOTREACHED */
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get a character, performing $ substitution unless flag is 0.
|
||||
* Any QUOTES character which is returned from a $ expansion is
|
||||
* QUOTEd so that it will not be recognized above.
|
||||
*/
|
||||
static int
|
||||
DgetC(int flag)
|
||||
{
|
||||
int c;
|
||||
top:
|
||||
if ((c = Dpeekc) != '\0') {
|
||||
Dpeekc = 0;
|
||||
return (c);
|
||||
}
|
||||
if (lap) {
|
||||
c = *lap++ & (QUOTE | TRIM);
|
||||
if (c == 0) {
|
||||
lap = 0;
|
||||
goto top;
|
||||
}
|
||||
quotspec:
|
||||
if (cmap(c, QUOTES))
|
||||
return (c | QUOTE);
|
||||
return (c);
|
||||
}
|
||||
if (dolp) {
|
||||
if ((c = *dolp++ & (QUOTE | TRIM)) != '\0')
|
||||
goto quotspec;
|
||||
if (dolcnt > 0) {
|
||||
setDolp(*dolnxt++);
|
||||
--dolcnt;
|
||||
return (' ');
|
||||
}
|
||||
dolp = 0;
|
||||
}
|
||||
if (dolcnt > 0) {
|
||||
setDolp(*dolnxt++);
|
||||
--dolcnt;
|
||||
goto top;
|
||||
}
|
||||
c = Dredc();
|
||||
if (c == '$' && flag) {
|
||||
Dgetdol();
|
||||
goto top;
|
||||
}
|
||||
return (c);
|
||||
}
|
||||
|
||||
static Char *nulvec[] = {0};
|
||||
static struct varent nulargv = {nulvec, STRargv, { NULL, NULL, NULL }, 0};
|
||||
|
||||
static void
|
||||
dolerror(Char *s)
|
||||
{
|
||||
setname(vis_str(s));
|
||||
stderror(ERR_NAME | ERR_RANGE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle the multitudinous $ expansion forms.
|
||||
* Ugh.
|
||||
*/
|
||||
static void
|
||||
Dgetdol(void)
|
||||
{
|
||||
static Char *dolbang = NULL;
|
||||
Char name[4*MAXVARLEN+1];
|
||||
Char wbuf[BUFSIZE];
|
||||
struct varent *vp;
|
||||
Char *np;
|
||||
int c, lwb, sc, subscr, upb;
|
||||
int dimen, bitset;
|
||||
char tnp;
|
||||
|
||||
bitset = 0;
|
||||
dimen = 0;
|
||||
lwb = 1;
|
||||
upb = 0;
|
||||
subscr = 0;
|
||||
vp = NULL;
|
||||
|
||||
dolnmod = dolmcnt = dolwcnt = 0;
|
||||
c = sc = DgetC(0);
|
||||
if (c == '{')
|
||||
c = DgetC(0); /* sc is { to take } later */
|
||||
if ((c & TRIM) == '#')
|
||||
dimen++, c = DgetC(0); /* $# takes dimension */
|
||||
else if (c == '?')
|
||||
bitset++, c = DgetC(0); /* $? tests existence */
|
||||
switch (c) {
|
||||
case '!':
|
||||
if (dimen || bitset)
|
||||
stderror(ERR_SYNTAX);
|
||||
if (backpid != 0) {
|
||||
if (dolbang)
|
||||
xfree((ptr_t)dolbang);
|
||||
setDolp(dolbang = putn(backpid));
|
||||
}
|
||||
goto eatbrac;
|
||||
case '$':
|
||||
if (dimen || bitset)
|
||||
stderror(ERR_SYNTAX);
|
||||
setDolp(doldol);
|
||||
goto eatbrac;
|
||||
case '<' | QUOTE:
|
||||
if (bitset)
|
||||
stderror(ERR_NOTALLOWED, "$?<");
|
||||
if (dimen)
|
||||
stderror(ERR_NOTALLOWED, "$?#");
|
||||
for (np = wbuf; read(OLDSTD, &tnp, 1) == 1; np++) {
|
||||
*np = (unsigned char)tnp;
|
||||
if (np >= &wbuf[BUFSIZE - 1])
|
||||
stderror(ERR_LTOOLONG);
|
||||
if (tnp == '\n')
|
||||
break;
|
||||
}
|
||||
*np = 0;
|
||||
/*
|
||||
* KLUDGE: dolmod is set here because it will cause setDolp to call
|
||||
* domod and thus to copy wbuf. Otherwise setDolp would use it
|
||||
* directly. If we saved it ourselves, no one would know when to free
|
||||
* it. The actual function of the 'q' causes filename expansion not to
|
||||
* be done on the interpolated value.
|
||||
*/
|
||||
dolmod[dolnmod++] = 'q';
|
||||
dolmcnt = 10000;
|
||||
setDolp(wbuf);
|
||||
goto eatbrac;
|
||||
case DEOF:
|
||||
case '\n':
|
||||
stderror(ERR_SYNTAX);
|
||||
/* NOTREACHED */
|
||||
case '*':
|
||||
(void) Strcpy(name, STRargv);
|
||||
vp = adrof(STRargv);
|
||||
subscr = -1; /* Prevent eating [...] */
|
||||
break;
|
||||
default:
|
||||
np = name;
|
||||
if (Isdigit(c)) {
|
||||
if (dimen)
|
||||
stderror(ERR_NOTALLOWED, "$#<num>");
|
||||
subscr = 0;
|
||||
do {
|
||||
subscr = subscr * 10 + c - '0';
|
||||
c = DgetC(0);
|
||||
} while (Isdigit(c));
|
||||
unDredc(c);
|
||||
if (subscr < 0)
|
||||
stderror(ERR_RANGE);
|
||||
if (subscr == 0) {
|
||||
if (bitset) {
|
||||
dolp = ffile ? STR1 : STR0;
|
||||
goto eatbrac;
|
||||
}
|
||||
if (ffile == 0)
|
||||
stderror(ERR_DOLZERO);
|
||||
fixDolMod();
|
||||
setDolp(ffile);
|
||||
goto eatbrac;
|
||||
}
|
||||
if (bitset)
|
||||
stderror(ERR_DOLQUEST);
|
||||
vp = adrof(STRargv);
|
||||
if (vp == 0) {
|
||||
vp = &nulargv;
|
||||
goto eatmod;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!alnum(c))
|
||||
stderror(ERR_VARALNUM);
|
||||
for (;;) {
|
||||
*np++ = (Char)c;
|
||||
c = DgetC(0);
|
||||
if (!alnum(c))
|
||||
break;
|
||||
if (np >= &name[MAXVARLEN])
|
||||
stderror(ERR_VARTOOLONG);
|
||||
}
|
||||
*np++ = 0;
|
||||
unDredc(c);
|
||||
vp = adrof(name);
|
||||
}
|
||||
if (bitset) {
|
||||
dolp = (vp || getenv(short2str(name))) ? STR1 : STR0;
|
||||
goto eatbrac;
|
||||
}
|
||||
if (vp == 0) {
|
||||
np = str2short(getenv(short2str(name)));
|
||||
if (np) {
|
||||
fixDolMod();
|
||||
setDolp(np);
|
||||
goto eatbrac;
|
||||
}
|
||||
udvar(name);
|
||||
}
|
||||
c = DgetC(0);
|
||||
upb = blklen(vp->vec);
|
||||
if (dimen == 0 && subscr == 0 && c == '[') {
|
||||
np = name;
|
||||
for (;;) {
|
||||
c = DgetC(DODOL); /* Allow $ expand within [ ] */
|
||||
if (c == ']')
|
||||
break;
|
||||
if (c == '\n' || c == DEOF)
|
||||
stderror(ERR_INCBR);
|
||||
if (np >= &name[sizeof(name) / sizeof(Char) - 2])
|
||||
stderror(ERR_VARTOOLONG);
|
||||
*np++ = (Char)c;
|
||||
}
|
||||
*np = 0, np = name;
|
||||
if (dolp || dolcnt) /* $ exp must end before ] */
|
||||
stderror(ERR_EXPORD);
|
||||
if (!*np)
|
||||
stderror(ERR_SYNTAX);
|
||||
if (Isdigit(*np)) {
|
||||
int i;
|
||||
|
||||
for (i = 0; Isdigit(*np); i = i * 10 + *np++ - '0')
|
||||
continue;
|
||||
if ((i < 0 || i > upb) && !any("-*", *np)) {
|
||||
dolerror(vp->v_name);
|
||||
return;
|
||||
}
|
||||
lwb = i;
|
||||
if (!*np)
|
||||
upb = lwb, np = STRstar;
|
||||
}
|
||||
if (*np == '*')
|
||||
np++;
|
||||
else if (*np != '-')
|
||||
stderror(ERR_MISSING, '-');
|
||||
else {
|
||||
int i = upb;
|
||||
|
||||
np++;
|
||||
if (Isdigit(*np)) {
|
||||
i = 0;
|
||||
while (Isdigit(*np))
|
||||
i = i * 10 + *np++ - '0';
|
||||
if (i < 0 || i > upb) {
|
||||
dolerror(vp->v_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (i < lwb)
|
||||
upb = lwb - 1;
|
||||
else
|
||||
upb = i;
|
||||
}
|
||||
if (lwb == 0) {
|
||||
if (upb != 0) {
|
||||
dolerror(vp->v_name);
|
||||
return;
|
||||
}
|
||||
upb = -1;
|
||||
}
|
||||
if (*np)
|
||||
stderror(ERR_SYNTAX);
|
||||
}
|
||||
else {
|
||||
if (subscr > 0) {
|
||||
if (subscr > upb)
|
||||
lwb = 1, upb = 0;
|
||||
else
|
||||
lwb = upb = subscr;
|
||||
}
|
||||
unDredc(c);
|
||||
}
|
||||
if (dimen) {
|
||||
Char *cp = putn(upb - lwb + 1);
|
||||
|
||||
addla(cp);
|
||||
xfree((ptr_t) cp);
|
||||
}
|
||||
else {
|
||||
eatmod:
|
||||
fixDolMod();
|
||||
dolnxt = &vp->vec[lwb - 1];
|
||||
dolcnt = upb - lwb + 1;
|
||||
}
|
||||
eatbrac:
|
||||
if (sc == '{') {
|
||||
c = Dredc();
|
||||
if (c != '}')
|
||||
stderror(ERR_MISSING, '}');
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fixDolMod(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = DgetC(0);
|
||||
if (c == ':') {
|
||||
do {
|
||||
c = DgetC(0), dolmcnt = 1, dolwcnt = 1;
|
||||
if (c == 'g' || c == 'a') {
|
||||
if (c == 'g')
|
||||
dolmcnt = 10000;
|
||||
else
|
||||
dolwcnt = 10000;
|
||||
c = DgetC(0);
|
||||
}
|
||||
if ((c == 'g' && dolmcnt != 10000) ||
|
||||
(c == 'a' && dolwcnt != 10000)) {
|
||||
if (c == 'g')
|
||||
dolmcnt = 10000;
|
||||
else
|
||||
dolwcnt = 10000;
|
||||
c = DgetC(0);
|
||||
}
|
||||
|
||||
if (c == 's') { /* [eichin:19910926.0755EST] */
|
||||
int delimcnt = 2;
|
||||
int delim = DgetC(0);
|
||||
dolmod[dolnmod++] = (Char)c;
|
||||
dolmod[dolnmod++] = (Char)delim;
|
||||
|
||||
if (!delim || letter(delim)
|
||||
|| Isdigit(delim) || any(" \t\n", delim)) {
|
||||
seterror(ERR_BADSUBST);
|
||||
break;
|
||||
}
|
||||
while ((c = DgetC(0)) != (-1)) {
|
||||
dolmod[dolnmod++] = (Char)c;
|
||||
if(c == delim) delimcnt--;
|
||||
if(!delimcnt) break;
|
||||
}
|
||||
if(delimcnt) {
|
||||
seterror(ERR_BADSUBST);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!any("htrqxes", c))
|
||||
stderror(ERR_BADMOD, c);
|
||||
dolmod[dolnmod++] = (Char)c;
|
||||
if (c == 'q')
|
||||
dolmcnt = 10000;
|
||||
}
|
||||
while ((c = DgetC(0)) == ':');
|
||||
unDredc(c);
|
||||
}
|
||||
else
|
||||
unDredc(c);
|
||||
}
|
||||
|
||||
static void
|
||||
setDolp(Char *cp)
|
||||
{
|
||||
Char *dp;
|
||||
int i;
|
||||
|
||||
if (dolnmod == 0 || dolmcnt == 0) {
|
||||
dolp = cp;
|
||||
return;
|
||||
}
|
||||
dp = cp = Strsave(cp);
|
||||
for (i = 0; i < dolnmod; i++) {
|
||||
/* handle s// [eichin:19910926.0510EST] */
|
||||
if(dolmod[i] == 's') {
|
||||
int delim;
|
||||
Char *lhsub, *rhsub, *np;
|
||||
size_t lhlen = 0, rhlen = 0;
|
||||
int didmod = 0;
|
||||
|
||||
delim = dolmod[++i];
|
||||
if (!delim || letter(delim)
|
||||
|| Isdigit(delim) || any(" \t\n", delim)) {
|
||||
seterror(ERR_BADSUBST);
|
||||
break;
|
||||
}
|
||||
lhsub = &dolmod[++i];
|
||||
while(dolmod[i] != delim && dolmod[++i]) {
|
||||
lhlen++;
|
||||
}
|
||||
dolmod[i] = 0;
|
||||
rhsub = &dolmod[++i];
|
||||
while(dolmod[i] != delim && dolmod[++i]) {
|
||||
rhlen++;
|
||||
}
|
||||
dolmod[i] = 0;
|
||||
|
||||
do {
|
||||
dp = Strstr(cp, lhsub);
|
||||
if (dp) {
|
||||
np = xmalloc(
|
||||
(size_t)((Strlen(cp) + 1 - lhlen + rhlen) *
|
||||
sizeof(*np)));
|
||||
(void)Strncpy(np, cp, (size_t)(dp - cp));
|
||||
(void)Strcpy(np + (dp - cp), rhsub);
|
||||
(void)Strcpy(np + (dp - cp) + rhlen, dp + lhlen);
|
||||
|
||||
xfree((ptr_t) cp);
|
||||
dp = cp = np;
|
||||
didmod = 1;
|
||||
} else {
|
||||
/* should this do a seterror? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (dolwcnt == 10000);
|
||||
/*
|
||||
* restore dolmod for additional words
|
||||
*/
|
||||
dolmod[i] = rhsub[-1] = (Char)delim;
|
||||
if (didmod)
|
||||
dolmcnt--;
|
||||
else
|
||||
break;
|
||||
} else {
|
||||
int didmod = 0;
|
||||
|
||||
do {
|
||||
if ((dp = domod(cp, dolmod[i]))) {
|
||||
didmod = 1;
|
||||
if (Strcmp(cp, dp) == 0) {
|
||||
xfree((ptr_t) cp);
|
||||
cp = dp;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
xfree((ptr_t) cp);
|
||||
cp = dp;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
while (dolwcnt == 10000);
|
||||
dp = cp;
|
||||
if (didmod)
|
||||
dolmcnt--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dp) {
|
||||
addla(dp);
|
||||
xfree((ptr_t) dp);
|
||||
}
|
||||
else {
|
||||
addla(cp);
|
||||
xfree((ptr_t) cp);
|
||||
}
|
||||
|
||||
dolp = STRNULL;
|
||||
if (seterr)
|
||||
stderror(ERR_OLD);
|
||||
}
|
||||
|
||||
static void
|
||||
unDredc(int c)
|
||||
{
|
||||
Dpeekrd = c;
|
||||
}
|
||||
|
||||
static int
|
||||
Dredc(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
if ((c = Dpeekrd) != '\0') {
|
||||
Dpeekrd = 0;
|
||||
return (c);
|
||||
}
|
||||
if (Dcp && (c = *Dcp++))
|
||||
return (c & (QUOTE | TRIM));
|
||||
if (*Dvp == 0) {
|
||||
Dcp = 0;
|
||||
return (DEOF);
|
||||
}
|
||||
Dcp = *Dvp++;
|
||||
return (' ');
|
||||
}
|
||||
|
||||
static void
|
||||
Dtestq(int c)
|
||||
{
|
||||
if (cmap(c, QUOTES))
|
||||
gflag = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Form a shell temporary file (in unit 0) from the words
|
||||
* of the shell input up to EOF or a line the same as "term".
|
||||
* Unit 0 should have been closed before this call.
|
||||
*/
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
heredoc(Char *term)
|
||||
{
|
||||
Char obuf[BUFSIZE], lbuf[BUFSIZE], mbuf[BUFSIZE];
|
||||
struct timespec tv;
|
||||
Char *Dv[2], *lbp, *obp, *mbp, **vp;
|
||||
char *tmp;
|
||||
int c, ocnt, lcnt, mcnt;
|
||||
int quoted;
|
||||
|
||||
again:
|
||||
tmp = short2str(shtemp);
|
||||
if (open(tmp, O_RDWR | O_CREAT | O_TRUNC | O_EXCL, 0600) < 0) {
|
||||
if (errno == EEXIST) {
|
||||
if (unlink(tmp) == -1) {
|
||||
(void)clock_gettime(CLOCK_MONOTONIC, &tv);
|
||||
mbp = putn((((int)tv.tv_sec) ^
|
||||
((int)tv.tv_nsec) ^ ((int)getpid())) & 0x00ffffff);
|
||||
shtemp = Strspl(STRtmpsh, mbp);
|
||||
xfree((ptr_t)mbp);
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
}
|
||||
(void)unlink(tmp); /* 0 0 inode! */
|
||||
Dv[0] = term;
|
||||
Dv[1] = NULL;
|
||||
gflag = 0;
|
||||
trim(Dv);
|
||||
rscan(Dv, Dtestq);
|
||||
quoted = gflag;
|
||||
ocnt = BUFSIZE;
|
||||
obp = obuf;
|
||||
for (;;) {
|
||||
/*
|
||||
* Read up a line
|
||||
*/
|
||||
lbp = lbuf;
|
||||
lcnt = BUFSIZE - 4;
|
||||
for (;;) {
|
||||
c = readc(1); /* 1 -> Want EOF returns */
|
||||
if (c < 0 || c == '\n')
|
||||
break;
|
||||
if ((c &= TRIM) != '\0') {
|
||||
*lbp++ = (Char)c;
|
||||
if (--lcnt < 0) {
|
||||
setname("<<");
|
||||
stderror(ERR_NAME | ERR_OVERFLOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
*lbp = 0;
|
||||
|
||||
/*
|
||||
* Check for EOF or compare to terminator -- before expansion
|
||||
*/
|
||||
if (c < 0 || eq(lbuf, term)) {
|
||||
(void)write(0, short2str(obuf), (size_t)(BUFSIZE - ocnt));
|
||||
(void)lseek(0, (off_t)0, SEEK_SET);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If term was quoted or -n just pass it on
|
||||
*/
|
||||
if (quoted || noexec) {
|
||||
*lbp++ = '\n';
|
||||
*lbp = 0;
|
||||
for (lbp = lbuf; (c = *lbp++) != '\0';) {
|
||||
*obp++ = (Char)c;
|
||||
if (--ocnt == 0) {
|
||||
(void) write(0, short2str(obuf), BUFSIZE);
|
||||
obp = obuf;
|
||||
ocnt = BUFSIZE;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Term wasn't quoted so variable and then command expand the input
|
||||
* line
|
||||
*/
|
||||
Dcp = lbuf;
|
||||
Dvp = Dv + 1;
|
||||
mbp = mbuf;
|
||||
mcnt = BUFSIZE - 4;
|
||||
for (;;) {
|
||||
c = DgetC(DODOL);
|
||||
if (c == DEOF)
|
||||
break;
|
||||
if ((c &= TRIM) == 0)
|
||||
continue;
|
||||
/* \ quotes \ $ ` here */
|
||||
if (c == '\\') {
|
||||
c = DgetC(0);
|
||||
if (!any("$\\`", c))
|
||||
unDgetC(c | QUOTE), c = '\\';
|
||||
else
|
||||
c |= QUOTE;
|
||||
}
|
||||
*mbp++ = (Char)c;
|
||||
if (--mcnt == 0) {
|
||||
setname("<<");
|
||||
stderror(ERR_NAME | ERR_OVERFLOW);
|
||||
}
|
||||
}
|
||||
*mbp++ = 0;
|
||||
|
||||
/*
|
||||
* If any ` in line do command substitution
|
||||
*/
|
||||
mbp = mbuf;
|
||||
if (any(short2str(mbp), '`')) {
|
||||
/*
|
||||
* 1 arg to dobackp causes substitution to be literal. Words are
|
||||
* broken only at newlines so that all blanks and tabs are
|
||||
* preserved. Blank lines (null words) are not discarded.
|
||||
*/
|
||||
vp = dobackp(mbuf, 1);
|
||||
}
|
||||
else
|
||||
/* Setup trivial vector similar to return of dobackp */
|
||||
Dv[0] = mbp, Dv[1] = NULL, vp = Dv;
|
||||
|
||||
/*
|
||||
* Resurrect the words from the command substitution each separated by
|
||||
* a newline. Note that the last newline of a command substitution
|
||||
* will have been discarded, but we put a newline after the last word
|
||||
* because this represents the newline after the last input line!
|
||||
*/
|
||||
for (; *vp; vp++) {
|
||||
for (mbp = *vp; *mbp; mbp++) {
|
||||
*obp++ = *mbp & TRIM;
|
||||
if (--ocnt == 0) {
|
||||
(void)write(0, short2str(obuf), BUFSIZE);
|
||||
obp = obuf;
|
||||
ocnt = BUFSIZE;
|
||||
}
|
||||
}
|
||||
*obp++ = '\n';
|
||||
if (--ocnt == 0) {
|
||||
(void)write(0, short2str(obuf), BUFSIZE);
|
||||
obp = obuf;
|
||||
ocnt = BUFSIZE;
|
||||
}
|
||||
}
|
||||
if (pargv)
|
||||
blkfree(pargv), pargv = 0;
|
||||
}
|
||||
}
|
||||
388
bin/csh/err.c
Normal file
388
bin/csh/err.c
Normal file
@@ -0,0 +1,388 @@
|
||||
/* $NetBSD: err.c,v 1.21 2013/07/16 17:47:43 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)err.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: err.c,v 1.21 2013/07/16 17:47:43 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
char *seterr = NULL; /* Holds last error if there was one */
|
||||
|
||||
#define ERR_FLAGS ((int)0xf0000000)
|
||||
#define ERR_NAME 0x10000000
|
||||
#define ERR_SILENT 0x20000000
|
||||
#define ERR_OLD 0x40000000
|
||||
|
||||
static const char *errorlist[] =
|
||||
{
|
||||
#define ERR_SYNTAX 0
|
||||
"Syntax Error",
|
||||
#define ERR_NOTALLOWED 1
|
||||
"%s is not allowed",
|
||||
#define ERR_WTOOLONG 2
|
||||
"Word too long",
|
||||
#define ERR_LTOOLONG 3
|
||||
"$< line too long",
|
||||
#define ERR_DOLZERO 4
|
||||
"No file for $0",
|
||||
#define ERR_DOLQUEST 5
|
||||
"$? not allowed here",
|
||||
#define ERR_INCBR 6
|
||||
"Incomplete [] modifier",
|
||||
#define ERR_EXPORD 7
|
||||
"$ expansion must end before ]",
|
||||
#define ERR_BADMOD 8
|
||||
"Bad : modifier in $ (%c)",
|
||||
#define ERR_SUBSCRIPT 9
|
||||
"Subscript error",
|
||||
#define ERR_BADNUM 10
|
||||
"Badly formed number",
|
||||
#define ERR_NOMORE 11
|
||||
"No more words",
|
||||
#define ERR_FILENAME 12
|
||||
"Missing file name",
|
||||
#define ERR_GLOB 13
|
||||
"Internal glob error",
|
||||
#define ERR_COMMAND 14
|
||||
"Command not found",
|
||||
#define ERR_TOOFEW 15
|
||||
"Too few arguments",
|
||||
#define ERR_TOOMANY 16
|
||||
"Too many arguments",
|
||||
#define ERR_DANGER 17
|
||||
"Too dangerous to alias that",
|
||||
#define ERR_EMPTYIF 18
|
||||
"Empty if",
|
||||
#define ERR_IMPRTHEN 19
|
||||
"Improper then",
|
||||
#define ERR_NOPAREN 20
|
||||
"Words not parenthesized",
|
||||
#define ERR_NOTFOUND 21
|
||||
"%s not found",
|
||||
#define ERR_MASK 22
|
||||
"Improper mask",
|
||||
#define ERR_LIMIT 23
|
||||
"No such limit",
|
||||
#define ERR_TOOLARGE 24
|
||||
"Argument too large",
|
||||
#define ERR_SCALEF 25
|
||||
"Improper or unknown scale factor",
|
||||
#define ERR_UNDVAR 26
|
||||
"Undefined variable",
|
||||
#define ERR_DEEP 27
|
||||
"Directory stack not that deep",
|
||||
#define ERR_BADSIG 28
|
||||
"Bad signal number",
|
||||
#define ERR_UNKSIG 29
|
||||
"Unknown signal; kill -l lists signals",
|
||||
#define ERR_VARBEGIN 30
|
||||
"Variable name must begin with a letter",
|
||||
#define ERR_VARTOOLONG 31
|
||||
"Variable name too long",
|
||||
#define ERR_VARALNUM 32
|
||||
"Variable name must contain alphanumeric characters",
|
||||
#define ERR_JOBCONTROL 33
|
||||
"No job control in this shell",
|
||||
#define ERR_EXPRESSION 34
|
||||
"Expression Syntax",
|
||||
#define ERR_NOHOMEDIR 35
|
||||
"No home directory",
|
||||
#define ERR_CANTCHANGE 36
|
||||
"Can't change to home directory",
|
||||
#define ERR_NULLCOM 37
|
||||
"Invalid null command",
|
||||
#define ERR_ASSIGN 38
|
||||
"Assignment missing expression",
|
||||
#define ERR_UNKNOWNOP 39
|
||||
"Unknown operator",
|
||||
#define ERR_AMBIG 40
|
||||
"Ambiguous",
|
||||
#define ERR_EXISTS 41
|
||||
"%s: File exists",
|
||||
#define ERR_INTR 42
|
||||
"Interrupted",
|
||||
#define ERR_RANGE 43
|
||||
"Subscript out of range",
|
||||
#define ERR_OVERFLOW 44
|
||||
"Line overflow",
|
||||
#define ERR_VARMOD 45
|
||||
"Unknown variable modifier",
|
||||
#define ERR_NOSUCHJOB 46
|
||||
"No such job",
|
||||
#define ERR_TERMINAL 47
|
||||
"Can't from terminal",
|
||||
#define ERR_NOTWHILE 48
|
||||
"Not in while/foreach",
|
||||
#define ERR_NOPROC 49
|
||||
"No more processes",
|
||||
#define ERR_NOMATCH 50
|
||||
"No match",
|
||||
#define ERR_MISSING 51
|
||||
"Missing %c",
|
||||
#define ERR_UNMATCHED 52
|
||||
"Unmatched %c",
|
||||
#define ERR_NOMEM 53
|
||||
"Out of memory",
|
||||
#define ERR_PIPE 54
|
||||
"Can't make pipe",
|
||||
#define ERR_SYSTEM 55
|
||||
"%s: %s",
|
||||
#define ERR_STRING 56
|
||||
"%s",
|
||||
#define ERR_JOBS 57
|
||||
"usage: jobs [ -l ]",
|
||||
#define ERR_JOBARGS 58
|
||||
"Arguments should be jobs or process id's",
|
||||
#define ERR_JOBCUR 59
|
||||
"No current job",
|
||||
#define ERR_JOBPREV 60
|
||||
"No previous job",
|
||||
#define ERR_JOBPAT 61
|
||||
"No job matches pattern",
|
||||
#define ERR_NESTING 62
|
||||
"Fork nesting > %d; maybe `...` loop",
|
||||
#define ERR_JOBCTRLSUB 63
|
||||
"No job control in subshells",
|
||||
#define ERR_BADPLPS 64
|
||||
"Badly placed ()'s",
|
||||
#define ERR_STOPPED 65
|
||||
"%sThere are suspended jobs",
|
||||
#define ERR_NODIR 66
|
||||
"No other directory",
|
||||
#define ERR_EMPTY 67
|
||||
"Directory stack empty",
|
||||
#define ERR_BADDIR 68
|
||||
"Bad directory",
|
||||
#define ERR_DIRUS 69
|
||||
"usage: %s [-lvn]%s",
|
||||
#define ERR_HFLAG 70
|
||||
"No operand for -h flag",
|
||||
#define ERR_NOTLOGIN 71
|
||||
"Not a login shell",
|
||||
#define ERR_DIV0 72
|
||||
"Division by 0",
|
||||
#define ERR_MOD0 73
|
||||
"Mod by 0",
|
||||
#define ERR_BADSCALE 74
|
||||
"Bad scaling; did you mean \"%s\"?",
|
||||
#define ERR_SUSPLOG 75
|
||||
"Can't suspend a login shell (yet)",
|
||||
#define ERR_UNKUSER 76
|
||||
"Unknown user: %s",
|
||||
#define ERR_NOHOME 77
|
||||
"No $home variable set",
|
||||
#define ERR_HISTUS 78
|
||||
"usage: history [-rh] [# number of events]",
|
||||
#define ERR_SPDOLLT 79
|
||||
"$, ! or < not allowed with $# or $?",
|
||||
#define ERR_NEWLINE 80
|
||||
"Newline in variable name",
|
||||
#define ERR_SPSTAR 81
|
||||
"* not allowed with $# or $?",
|
||||
#define ERR_DIGIT 82
|
||||
"$?<digit> or $#<digit> not allowed",
|
||||
#define ERR_VARILL 83
|
||||
"Illegal variable name",
|
||||
#define ERR_NLINDEX 84
|
||||
"Newline in variable index",
|
||||
#define ERR_EXPOVFL 85
|
||||
"Expansion buffer overflow",
|
||||
#define ERR_VARSYN 86
|
||||
"Variable syntax",
|
||||
#define ERR_BADBANG 87
|
||||
"Bad ! form",
|
||||
#define ERR_NOSUBST 88
|
||||
"No previous substitute",
|
||||
#define ERR_BADSUBST 89
|
||||
"Bad substitute",
|
||||
#define ERR_LHS 90
|
||||
"No previous left hand side",
|
||||
#define ERR_RHSLONG 91
|
||||
"Right hand side too long",
|
||||
#define ERR_BADBANGMOD 92
|
||||
"Bad ! modifier: %c",
|
||||
#define ERR_MODFAIL 93
|
||||
"Modifier failed",
|
||||
#define ERR_SUBOVFL 94
|
||||
"Substitution buffer overflow",
|
||||
#define ERR_BADBANGARG 95
|
||||
"Bad ! arg selector",
|
||||
#define ERR_NOSEARCH 96
|
||||
"No prev search",
|
||||
#define ERR_NOEVENT 97
|
||||
"%s: Event not found",
|
||||
#define ERR_TOOMANYRP 98
|
||||
"Too many )'s",
|
||||
#define ERR_TOOMANYLP 99
|
||||
"Too many ('s",
|
||||
#define ERR_BADPLP 100
|
||||
"Badly placed (",
|
||||
#define ERR_MISRED 101
|
||||
"Missing name for redirect",
|
||||
#define ERR_OUTRED 102
|
||||
"Ambiguous output redirect",
|
||||
#define ERR_REDPAR 103
|
||||
"Can't << within ()'s",
|
||||
#define ERR_INRED 104
|
||||
"Ambiguous input redirect",
|
||||
#define ERR_ALIASLOOP 105
|
||||
"Alias loop",
|
||||
#define ERR_HISTLOOP 106
|
||||
"!# History loop",
|
||||
#define ERR_ARCH 107
|
||||
"%s: %s. Wrong Architecture",
|
||||
#define ERR_FILEINQ 108
|
||||
"Malformed file inquiry",
|
||||
#define ERR_SELOVFL 109
|
||||
"Selector overflow",
|
||||
#define ERR_INVALID 110
|
||||
"Invalid Error"
|
||||
};
|
||||
|
||||
/*
|
||||
* The parser and scanner set up errors for later by calling seterr,
|
||||
* which sets the variable err as a side effect; later to be tested,
|
||||
* e.g. in process.
|
||||
*/
|
||||
void
|
||||
seterror(int id, ...)
|
||||
{
|
||||
if (seterr == 0) {
|
||||
char berr[BUFSIZE];
|
||||
va_list va;
|
||||
|
||||
va_start(va, id);
|
||||
if (id < 0 || id >= (int)(sizeof(errorlist) / sizeof(errorlist[0])) - 1)
|
||||
id = ERR_INVALID;
|
||||
(void)vsnprintf(berr, sizeof(berr), errorlist[id], va);
|
||||
va_end(va);
|
||||
|
||||
seterr = strsave(berr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the error with the given id.
|
||||
*
|
||||
* Special ids:
|
||||
* ERR_SILENT: Print nothing.
|
||||
* ERR_OLD: Print the previously set error if one was there.
|
||||
* otherwise return.
|
||||
* ERR_NAME: If this bit is set, print the name of the function
|
||||
* in bname
|
||||
*
|
||||
* This routine always resets or exits. The flag haderr
|
||||
* is set so the routine who catches the unwind can propogate
|
||||
* it if they want.
|
||||
*
|
||||
* Note that any open files at the point of error will eventually
|
||||
* be closed in the routine process in sh.c which is the only
|
||||
* place error unwinds are ever caught.
|
||||
*/
|
||||
void
|
||||
stderror(int id, ...)
|
||||
{
|
||||
va_list va;
|
||||
Char **v;
|
||||
int flags;
|
||||
|
||||
flags = id & ERR_FLAGS;
|
||||
id &= ~ERR_FLAGS;
|
||||
|
||||
if ((flags & ERR_OLD) && seterr == NULL)
|
||||
abort();
|
||||
|
||||
if (id < 0 || id > (int)(sizeof(errorlist) / sizeof(errorlist[0])))
|
||||
id = ERR_INVALID;
|
||||
|
||||
(void)fflush(cshout);
|
||||
(void)fflush(csherr);
|
||||
haderr = 1; /* Now to diagnostic output */
|
||||
timflg = 0; /* This isn't otherwise reset */
|
||||
|
||||
|
||||
if (!(flags & ERR_SILENT)) {
|
||||
if (flags & ERR_NAME)
|
||||
(void)fprintf(csherr, "%s: ", bname);
|
||||
if ((flags & ERR_OLD))
|
||||
/* Old error. */
|
||||
(void)fprintf(csherr, "%s.\n", seterr);
|
||||
else {
|
||||
va_start(va, id);
|
||||
(void)vfprintf(csherr, errorlist[id], va);
|
||||
va_end(va);
|
||||
(void)fprintf(csherr, ".\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (seterr) {
|
||||
xfree((ptr_t) seterr);
|
||||
seterr = NULL;
|
||||
}
|
||||
|
||||
if ((v = pargv) != NULL)
|
||||
pargv = 0, blkfree(v);
|
||||
if ((v = gargv) != NULL)
|
||||
gargv = 0, blkfree(v);
|
||||
|
||||
(void)fflush(cshout);
|
||||
(void)fflush(csherr);
|
||||
didfds = 0; /* Forget about 0,1,2 */
|
||||
/*
|
||||
* Go away if -e or we are a child shell
|
||||
*/
|
||||
if (exiterr || child)
|
||||
xexit(1);
|
||||
|
||||
/*
|
||||
* Reset the state of the input. This buffered seek to end of file will
|
||||
* also clear the while/foreach stack.
|
||||
*/
|
||||
btoeof();
|
||||
|
||||
set(STRstatus, Strsave(STR1));
|
||||
if (tpgrp > 0)
|
||||
(void)tcsetpgrp(FSHTTY, tpgrp);
|
||||
reset(); /* Unwind */
|
||||
}
|
||||
746
bin/csh/exec.c
Normal file
746
bin/csh/exec.c
Normal file
@@ -0,0 +1,746 @@
|
||||
/* $NetBSD: exec.c,v 1.29 2013/07/16 17:47:43 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)exec.c 8.3 (Berkeley) 5/23/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: exec.c,v 1.29 2013/07/16 17:47:43 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
/*
|
||||
* System level search and execute of a command. We look in each directory
|
||||
* for the specified command name. If the name contains a '/' then we
|
||||
* execute only the full path name. If there is no search path then we
|
||||
* execute only full path names.
|
||||
*/
|
||||
extern char **environ;
|
||||
|
||||
/*
|
||||
* As we search for the command we note the first non-trivial error
|
||||
* message for presentation to the user. This allows us often
|
||||
* to show that a file has the wrong mode/no access when the file
|
||||
* is not in the last component of the search path, so we must
|
||||
* go on after first detecting the error.
|
||||
*/
|
||||
static const char *exerr; /* Execution error message */
|
||||
static Char *expath; /* Path for exerr */
|
||||
|
||||
/*
|
||||
* Xhash is an array of HSHSIZ bits (HSHSIZ / 8 chars), which are used
|
||||
* to hash execs. If it is allocated (havhash true), then to tell
|
||||
* whether ``name'' is (possibly) present in the i'th component
|
||||
* of the variable path, you look at the bit in xhash indexed by
|
||||
* hash(hashname("name"), i). This is setup automatically
|
||||
* after .login is executed, and recomputed whenever ``path'' is
|
||||
* changed.
|
||||
* The two part hash function is designed to let texec() call the
|
||||
* more expensive hashname() only once and the simple hash() several
|
||||
* times (once for each path component checked).
|
||||
* Byte size is assumed to be 8.
|
||||
*/
|
||||
#define HSHSIZ 8192 /* 1k bytes */
|
||||
#define HSHMASK (HSHSIZ - 1)
|
||||
#define HSHMUL 243
|
||||
static unsigned char xhash[HSHSIZ / 8];
|
||||
|
||||
#define hash(a, b) (((a) * HSHMUL + (b)) & HSHMASK)
|
||||
#define bit(h, b) ((h)[(b) >> 3] & 1 << ((b) & 7)) /* bit test */
|
||||
#define bis(h, b) ((h)[(b) >> 3] |= (unsigned char)(1 << ((b) & 7))) /* bit set */
|
||||
static int hits, misses;
|
||||
|
||||
/* Dummy search path for just absolute search when no path */
|
||||
static Char *justabs[] = {STRNULL, 0};
|
||||
|
||||
static void pexerr(void) __dead;
|
||||
static void texec(Char *, Char **);
|
||||
static int hashname(Char *);
|
||||
static int tellmewhat(struct wordent *, Char *);
|
||||
static int executable(Char *, Char *, int);
|
||||
static int iscommand(Char *);
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
doexec(Char **v, struct command *t)
|
||||
{
|
||||
struct varent *pathv;
|
||||
Char *blk[2], **av, *dp, **pv, *sav;
|
||||
int i, hashval, hashval1;
|
||||
sigset_t nsigset;
|
||||
int slash;
|
||||
|
||||
hashval = 0;
|
||||
/*
|
||||
* Glob the command name. We will search $path even if this does something,
|
||||
* as in sh but not in csh. One special case: if there is no PATH, then we
|
||||
* execute only commands which start with '/'.
|
||||
*/
|
||||
blk[0] = t->t_dcom[0];
|
||||
blk[1] = 0;
|
||||
gflag = 0, tglob(blk);
|
||||
if (gflag) {
|
||||
pv = globall(blk);
|
||||
if (pv == 0) {
|
||||
setname(vis_str(blk[0]));
|
||||
stderror(ERR_NAME | ERR_NOMATCH);
|
||||
}
|
||||
gargv = 0;
|
||||
}
|
||||
else
|
||||
pv = saveblk(blk);
|
||||
|
||||
trim(pv);
|
||||
|
||||
exerr = 0;
|
||||
expath = Strsave(pv[0]);
|
||||
Vexpath = expath;
|
||||
|
||||
pathv = adrof(STRpath);
|
||||
if (pathv == 0 && expath[0] != '/') {
|
||||
blkfree(pv);
|
||||
pexerr();
|
||||
}
|
||||
slash = any(short2str(expath), '/');
|
||||
|
||||
/*
|
||||
* Glob the argument list, if necessary. Otherwise trim off the quote bits.
|
||||
*/
|
||||
gflag = 0;
|
||||
av = &t->t_dcom[1];
|
||||
tglob(av);
|
||||
if (gflag) {
|
||||
av = globall(av);
|
||||
if (av == 0) {
|
||||
blkfree(pv);
|
||||
setname(vis_str(expath));
|
||||
stderror(ERR_NAME | ERR_NOMATCH);
|
||||
}
|
||||
gargv = 0;
|
||||
}
|
||||
else
|
||||
av = saveblk(av);
|
||||
|
||||
blkfree(t->t_dcom);
|
||||
t->t_dcom = blkspl(pv, av);
|
||||
xfree((ptr_t) pv);
|
||||
xfree((ptr_t) av);
|
||||
av = t->t_dcom;
|
||||
trim(av);
|
||||
|
||||
if (*av == NULL || **av == '\0')
|
||||
pexerr();
|
||||
|
||||
xechoit(av); /* Echo command if -x */
|
||||
/*
|
||||
* Since all internal file descriptors are set to close on exec, we don't
|
||||
* need to close them explicitly here. Just reorient ourselves for error
|
||||
* messages.
|
||||
*/
|
||||
SHIN = 0;
|
||||
SHOUT = 1;
|
||||
SHERR = 2;
|
||||
OLDSTD = 0;
|
||||
/*
|
||||
* We must do this AFTER any possible forking (like `foo` in glob) so that
|
||||
* this shell can still do subprocesses.
|
||||
*/
|
||||
sigemptyset(&nsigset);
|
||||
(void)sigprocmask(SIG_SETMASK, &nsigset, NULL);
|
||||
/*
|
||||
* If no path, no words in path, or a / in the filename then restrict the
|
||||
* command search.
|
||||
*/
|
||||
if (pathv == 0 || pathv->vec[0] == 0 || slash)
|
||||
pv = justabs;
|
||||
else
|
||||
pv = pathv->vec;
|
||||
sav = Strspl(STRslash, *av); /* / command name for postpending */
|
||||
Vsav = sav;
|
||||
if (havhash)
|
||||
hashval = hashname(*av);
|
||||
i = 0;
|
||||
hits++;
|
||||
do {
|
||||
/*
|
||||
* Try to save time by looking at the hash table for where this command
|
||||
* could be. If we are doing delayed hashing, then we put the names in
|
||||
* one at a time, as the user enters them. This is kinda like Korn
|
||||
* Shell's "tracked aliases".
|
||||
*/
|
||||
if (!slash && pv[0][0] == '/' && havhash) {
|
||||
hashval1 = hash(hashval, i);
|
||||
if (!bit(xhash, hashval1))
|
||||
goto cont;
|
||||
}
|
||||
if (pv[0][0] == 0 || eq(pv[0], STRdot)) /* don't make ./xxx */
|
||||
texec(*av, av);
|
||||
else {
|
||||
dp = Strspl(*pv, sav);
|
||||
Vdp = dp;
|
||||
texec(dp, av);
|
||||
Vdp = 0;
|
||||
xfree((ptr_t)dp);
|
||||
}
|
||||
misses++;
|
||||
cont:
|
||||
pv++;
|
||||
i++;
|
||||
} while (*pv);
|
||||
hits--;
|
||||
Vsav = 0;
|
||||
xfree((ptr_t)sav);
|
||||
pexerr();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static void
|
||||
pexerr(void)
|
||||
{
|
||||
/* Couldn't find the damn thing */
|
||||
if (expath) {
|
||||
setname(vis_str(expath));
|
||||
Vexpath = 0;
|
||||
xfree((ptr_t)expath);
|
||||
expath = 0;
|
||||
}
|
||||
else
|
||||
setname("");
|
||||
if (exerr)
|
||||
stderror(ERR_NAME | ERR_STRING, exerr);
|
||||
else
|
||||
stderror(ERR_NAME | ERR_COMMAND);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute command f, arg list t.
|
||||
* Record error message if not found.
|
||||
* Also do shell scripts here.
|
||||
*/
|
||||
static void
|
||||
texec(Char *sf, Char **st)
|
||||
{
|
||||
struct varent *v;
|
||||
Char *lastsh[2], **vp, *st0, **ost;
|
||||
char *f, **t;
|
||||
int fd;
|
||||
unsigned char c = '\0';
|
||||
|
||||
/* The order for the conversions is significant */
|
||||
t = short2blk(st);
|
||||
f = short2str(sf);
|
||||
Vt = t;
|
||||
errno = 0; /* don't use a previous error */
|
||||
(void)execve(f, t, environ);
|
||||
Vt = 0;
|
||||
blkfree((Char **)t);
|
||||
switch (errno) {
|
||||
|
||||
case ENOEXEC:
|
||||
/*
|
||||
* From: casper@fwi.uva.nl (Casper H.S. Dik) If we could not execute
|
||||
* it, don't feed it to the shell if it looks like a binary!
|
||||
*/
|
||||
if ((fd = open(f, O_RDONLY)) != -1) {
|
||||
if (read(fd, (char *)&c, 1) == 1) {
|
||||
if (!Isprint(c) && (c != '\n' && c != '\t')) {
|
||||
(void)close(fd);
|
||||
/*
|
||||
* We *know* what ENOEXEC means.
|
||||
*/
|
||||
stderror(ERR_ARCH, f, strerror(errno));
|
||||
}
|
||||
}
|
||||
#ifdef _PATH_BSHELL
|
||||
else
|
||||
c = '#';
|
||||
#endif
|
||||
(void)close(fd);
|
||||
}
|
||||
/*
|
||||
* If there is an alias for shell, then put the words of the alias in
|
||||
* front of the argument list replacing the command name. Note no
|
||||
* interpretation of the words at this point.
|
||||
*/
|
||||
v = adrof1(STRshell, &aliases);
|
||||
if (v == 0) {
|
||||
vp = lastsh;
|
||||
vp[0] = adrof(STRshell) ? value(STRshell) : STR_SHELLPATH;
|
||||
vp[1] = NULL;
|
||||
#ifdef _PATH_BSHELL
|
||||
if (fd != -1 && c != '#')
|
||||
vp[0] = STR_BSHELL;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
vp = v->vec;
|
||||
st0 = st[0];
|
||||
st[0] = sf;
|
||||
ost = st;
|
||||
st = blkspl(vp, st); /* Splice up the new arglst */
|
||||
ost[0] = st0;
|
||||
sf = *st;
|
||||
/* The order for the conversions is significant */
|
||||
t = short2blk(st);
|
||||
f = short2str(sf);
|
||||
xfree((ptr_t) st);
|
||||
Vt = t;
|
||||
(void)execve(f, t, environ);
|
||||
Vt = 0;
|
||||
blkfree((Char **) t);
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case ENOMEM:
|
||||
stderror(ERR_SYSTEM, f, strerror(errno));
|
||||
/* NOTREACHED */
|
||||
|
||||
case ENOENT:
|
||||
break;
|
||||
|
||||
default:
|
||||
if (exerr == 0) {
|
||||
exerr = strerror(errno);
|
||||
if (expath)
|
||||
xfree((ptr_t) expath);
|
||||
expath = Strsave(sf);
|
||||
Vexpath = expath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
execash(Char **t, struct command *kp)
|
||||
{
|
||||
jmp_buf osetexit;
|
||||
sig_t osigint, osigquit, osigterm;
|
||||
int my_reenter, odidfds, oOLDSTD, oSHERR, oSHIN, oSHOUT;
|
||||
int saveDIAG, saveIN, saveOUT, saveSTD;
|
||||
|
||||
if (chkstop == 0 && setintr)
|
||||
panystop(0);
|
||||
/*
|
||||
* Hmm, we don't really want to do that now because we might
|
||||
* fail, but what is the choice
|
||||
*/
|
||||
rechist();
|
||||
|
||||
osigint = signal(SIGINT, parintr);
|
||||
osigquit = signal(SIGQUIT, parintr);
|
||||
osigterm = signal(SIGTERM, parterm);
|
||||
|
||||
odidfds = didfds;
|
||||
oSHIN = SHIN;
|
||||
oSHOUT = SHOUT;
|
||||
oSHERR = SHERR;
|
||||
oOLDSTD = OLDSTD;
|
||||
|
||||
saveIN = dcopy(SHIN, -1);
|
||||
saveOUT = dcopy(SHOUT, -1);
|
||||
saveDIAG = dcopy(SHERR, -1);
|
||||
saveSTD = dcopy(OLDSTD, -1);
|
||||
|
||||
lshift(kp->t_dcom, 1);
|
||||
|
||||
getexit(osetexit);
|
||||
|
||||
if ((my_reenter = setexit()) == 0) {
|
||||
SHIN = dcopy(0, -1);
|
||||
SHOUT = dcopy(1, -1);
|
||||
SHERR = dcopy(2, -1);
|
||||
didfds = 0;
|
||||
doexec(t, kp);
|
||||
}
|
||||
|
||||
(void)signal(SIGINT, osigint);
|
||||
(void)signal(SIGQUIT, osigquit);
|
||||
(void)signal(SIGTERM, osigterm);
|
||||
|
||||
doneinp = 0;
|
||||
didfds = odidfds;
|
||||
(void)close(SHIN);
|
||||
(void)close(SHOUT);
|
||||
(void)close(SHERR);
|
||||
(void)close(OLDSTD);
|
||||
SHIN = dmove(saveIN, oSHIN);
|
||||
SHOUT = dmove(saveOUT, oSHOUT);
|
||||
SHERR = dmove(saveDIAG, oSHERR);
|
||||
OLDSTD = dmove(saveSTD, oOLDSTD);
|
||||
|
||||
resexit(osetexit);
|
||||
if (my_reenter)
|
||||
stderror(ERR_SILENT);
|
||||
}
|
||||
|
||||
void
|
||||
xechoit(Char **t)
|
||||
{
|
||||
if (adrof(STRecho)) {
|
||||
int odidfds = didfds;
|
||||
(void)fflush(csherr);
|
||||
odidfds = didfds;
|
||||
didfds = 0;
|
||||
blkpr(csherr, t);
|
||||
(void)fputc('\n', csherr);
|
||||
(void)fflush(csherr);
|
||||
didfds = odidfds;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dohash(Char **v, struct command *t)
|
||||
{
|
||||
struct dirent *dp;
|
||||
struct varent *pathv;
|
||||
DIR *dirp;
|
||||
Char **pv;
|
||||
size_t cnt;
|
||||
int hashval, i;
|
||||
|
||||
i = 0;
|
||||
havhash = 1;
|
||||
pathv = adrof(STRpath);
|
||||
|
||||
for (cnt = 0; cnt < sizeof xhash; cnt++)
|
||||
xhash[cnt] = 0;
|
||||
if (pathv == 0)
|
||||
return;
|
||||
for (pv = pathv->vec; *pv; pv++, i++) {
|
||||
if (pv[0][0] != '/')
|
||||
continue;
|
||||
dirp = opendir(short2str(*pv));
|
||||
if (dirp == NULL)
|
||||
continue;
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
if (dp->d_ino == 0)
|
||||
continue;
|
||||
if (dp->d_name[0] == '.' &&
|
||||
(dp->d_name[1] == '\0' ||
|
||||
(dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
|
||||
continue;
|
||||
hashval = hash(hashname(str2short(dp->d_name)), i);
|
||||
bis(xhash, hashval);
|
||||
/* tw_add_comm_name (dp->d_name); */
|
||||
}
|
||||
(void) closedir(dirp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dounhash(Char **v, struct command *t)
|
||||
{
|
||||
havhash = 0;
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
hashstat(Char **v, struct command *t)
|
||||
{
|
||||
if (hits + misses)
|
||||
(void)fprintf(cshout, "%d hits, %d misses, %d%%\n",
|
||||
hits, misses, 100 * hits / (hits + misses));
|
||||
}
|
||||
|
||||
/*
|
||||
* Hash a command name.
|
||||
*/
|
||||
static int
|
||||
hashname(Char *cp)
|
||||
{
|
||||
long h = 0;
|
||||
|
||||
while (*cp)
|
||||
h = hash(h, *cp++);
|
||||
return ((int) h);
|
||||
}
|
||||
|
||||
static int
|
||||
iscommand(Char *name)
|
||||
{
|
||||
struct varent *v;
|
||||
Char **pv, *sav;
|
||||
int hashval, hashval1, i;
|
||||
int slash;
|
||||
|
||||
hashval = 0;
|
||||
slash = any(short2str(name), '/');
|
||||
v = adrof(STRpath);
|
||||
|
||||
if (v == 0 || v->vec[0] == 0 || slash)
|
||||
pv = justabs;
|
||||
else
|
||||
pv = v->vec;
|
||||
sav = Strspl(STRslash, name); /* / command name for postpending */
|
||||
if (havhash)
|
||||
hashval = hashname(name);
|
||||
i = 0;
|
||||
do {
|
||||
if (!slash && pv[0][0] == '/' && havhash) {
|
||||
hashval1 = hash(hashval, i);
|
||||
if (!bit(xhash, hashval1))
|
||||
goto cont;
|
||||
}
|
||||
if (pv[0][0] == 0 || eq(pv[0], STRdot)) { /* don't make ./xxx */
|
||||
if (executable(NULL, name, 0)) {
|
||||
xfree((ptr_t) sav);
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (executable(*pv, sav, 0)) {
|
||||
xfree((ptr_t) sav);
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
cont:
|
||||
pv++;
|
||||
i++;
|
||||
} while (*pv);
|
||||
xfree((ptr_t) sav);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Also by:
|
||||
* Andreas Luik <luik@isaak.isa.de>
|
||||
* I S A GmbH - Informationssysteme fuer computerintegrierte Automatisierung
|
||||
* Azenberstr. 35
|
||||
* D-7000 Stuttgart 1
|
||||
* West-Germany
|
||||
* is the executable() routine below and changes to iscommand().
|
||||
* Thanks again!!
|
||||
*/
|
||||
|
||||
/*
|
||||
* executable() examines the pathname obtained by concatenating dir and name
|
||||
* (dir may be NULL), and returns 1 either if it is executable by us, or
|
||||
* if dir_ok is set and the pathname refers to a directory.
|
||||
* This is a bit kludgy, but in the name of optimization...
|
||||
*/
|
||||
static int
|
||||
executable(Char *dir, Char *name, int dir_ok)
|
||||
{
|
||||
struct stat stbuf;
|
||||
Char path[MAXPATHLEN + 1], *dp, *sp;
|
||||
char *strname;
|
||||
|
||||
if (dir && *dir) {
|
||||
for (dp = path, sp = dir; *sp; *dp++ = *sp++)
|
||||
if (dp == &path[MAXPATHLEN + 1]) {
|
||||
*--dp = '\0';
|
||||
break;
|
||||
}
|
||||
for (sp = name; *sp; *dp++ = *sp++)
|
||||
if (dp == &path[MAXPATHLEN + 1]) {
|
||||
*--dp = '\0';
|
||||
break;
|
||||
}
|
||||
*dp = '\0';
|
||||
strname = short2str(path);
|
||||
}
|
||||
else
|
||||
strname = short2str(name);
|
||||
return (stat(strname, &stbuf) != -1 && ((S_ISREG(stbuf.st_mode) &&
|
||||
/* save time by not calling access() in the hopeless case */
|
||||
(stbuf.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR)) &&
|
||||
access(strname, X_OK) == 0) || (dir_ok && S_ISDIR(stbuf.st_mode))));
|
||||
}
|
||||
|
||||
/* The dowhich() is by:
|
||||
* Andreas Luik <luik@isaak.isa.de>
|
||||
* I S A GmbH - Informationssysteme fuer computerintegrierte Automatisierung
|
||||
* Azenberstr. 35
|
||||
* D-7000 Stuttgart 1
|
||||
* West-Germany
|
||||
* Thanks!!
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
dowhich(Char **v, struct command *c)
|
||||
{
|
||||
struct wordent lexw[3];
|
||||
struct varent *vp;
|
||||
|
||||
lexw[0].next = &lexw[1];
|
||||
lexw[1].next = &lexw[2];
|
||||
lexw[2].next = &lexw[0];
|
||||
|
||||
lexw[0].prev = &lexw[2];
|
||||
lexw[1].prev = &lexw[0];
|
||||
lexw[2].prev = &lexw[1];
|
||||
|
||||
lexw[0].word = STRNULL;
|
||||
lexw[2].word = STRret;
|
||||
|
||||
while (*++v) {
|
||||
if ((vp = adrof1(*v, &aliases)) != NULL) {
|
||||
(void)fprintf(cshout, "%s: \t aliased to ", vis_str(*v));
|
||||
blkpr(cshout, vp->vec);
|
||||
(void)fputc('\n', cshout);
|
||||
set(STRstatus, Strsave(STR0));
|
||||
}
|
||||
else {
|
||||
lexw[1].word = *v;
|
||||
set(STRstatus, Strsave(tellmewhat(lexw, NULL) ? STR0 : STR1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
tellmewhat(struct wordent *lexp, Char *str)
|
||||
{
|
||||
struct biltins *bptr;
|
||||
struct wordent *sp;
|
||||
Char *cmd, *s0, *s1, *s2;
|
||||
int i;
|
||||
int aliased, found;
|
||||
Char qc;
|
||||
|
||||
aliased = 0;
|
||||
sp = lexp->next;
|
||||
|
||||
if (adrof1(sp->word, &aliases)) {
|
||||
alias(lexp);
|
||||
sp = lexp->next;
|
||||
aliased = 1;
|
||||
}
|
||||
|
||||
s0 = sp->word; /* to get the memory freeing right... */
|
||||
|
||||
/* handle quoted alias hack */
|
||||
if ((*(sp->word) & (QUOTE | TRIM)) == QUOTE)
|
||||
(sp->word)++;
|
||||
|
||||
/* do quoting, if it hasn't been done */
|
||||
s1 = s2 = sp->word;
|
||||
while (*s2)
|
||||
switch (*s2) {
|
||||
case '\'':
|
||||
case '"':
|
||||
qc = *s2++;
|
||||
while (*s2 && *s2 != qc)
|
||||
*s1++ = (Char)(*s2++ | QUOTE);
|
||||
if (*s2)
|
||||
s2++;
|
||||
break;
|
||||
case '\\':
|
||||
if (*++s2)
|
||||
*s1++ = (Char)(*s2++ | QUOTE);
|
||||
break;
|
||||
default:
|
||||
*s1++ = *s2++;
|
||||
}
|
||||
*s1 = '\0';
|
||||
|
||||
for (bptr = bfunc; bptr < &bfunc[nbfunc]; bptr++) {
|
||||
if (eq(sp->word, str2short(bptr->bname))) {
|
||||
if (str == NULL) {
|
||||
if (aliased)
|
||||
prlex(cshout, lexp);
|
||||
(void)fprintf(cshout, "%s: shell built-in command.\n",
|
||||
vis_str(sp->word));
|
||||
}
|
||||
else
|
||||
(void)Strcpy(str, sp->word);
|
||||
sp->word = s0; /* we save and then restore this */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
sp->word = cmd = globone(sp->word, G_IGNORE);
|
||||
|
||||
if ((i = iscommand(sp->word)) != 0) {
|
||||
Char **pv;
|
||||
struct varent *v;
|
||||
int slash = any(short2str(sp->word), '/');
|
||||
|
||||
v = adrof(STRpath);
|
||||
if (v == 0 || v->vec[0] == 0 || slash)
|
||||
pv = justabs;
|
||||
else
|
||||
pv = v->vec;
|
||||
|
||||
while (--i)
|
||||
pv++;
|
||||
if (pv[0][0] == 0 || eq(pv[0], STRdot)) {
|
||||
if (!slash) {
|
||||
sp->word = Strspl(STRdotsl, sp->word);
|
||||
prlex(cshout, lexp);
|
||||
xfree((ptr_t) sp->word);
|
||||
}
|
||||
else
|
||||
prlex(cshout, lexp);
|
||||
}
|
||||
else {
|
||||
s1 = Strspl(*pv, STRslash);
|
||||
sp->word = Strspl(s1, sp->word);
|
||||
xfree((ptr_t) s1);
|
||||
if (str == NULL)
|
||||
prlex(cshout, lexp);
|
||||
else
|
||||
(void)Strcpy(str, sp->word);
|
||||
xfree((ptr_t) sp->word);
|
||||
}
|
||||
found = 1;
|
||||
}
|
||||
else {
|
||||
if (str == NULL) {
|
||||
if (aliased)
|
||||
prlex(cshout, lexp);
|
||||
(void)fprintf(csherr,
|
||||
"%s: Command not found.\n", vis_str(sp->word));
|
||||
}
|
||||
else
|
||||
(void)Strcpy(str, sp->word);
|
||||
found = 0;
|
||||
}
|
||||
sp->word = s0; /* we save and then restore this */
|
||||
xfree((ptr_t) cmd);
|
||||
return found;
|
||||
}
|
||||
661
bin/csh/exp.c
Normal file
661
bin/csh/exp.c
Normal file
@@ -0,0 +1,661 @@
|
||||
/* $NetBSD: exp.c,v 1.20 2009/02/14 07:12:29 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)exp.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: exp.c,v 1.20 2009/02/14 07:12:29 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef SHORT_STRINGS
|
||||
#include <string.h>
|
||||
#endif /* SHORT_STRINGS */
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
#define IGNORE 1 /* in ignore, it means to ignore value, just parse */
|
||||
#define NOGLOB 2 /* in ignore, it means not to globone */
|
||||
|
||||
#define ADDOP 1
|
||||
#define MULOP 2
|
||||
#define EQOP 4
|
||||
#define RELOP 8
|
||||
#define RESTOP 16
|
||||
#define ANYOP 31
|
||||
|
||||
#define EQEQ 1
|
||||
#define GTR 2
|
||||
#define LSS 4
|
||||
#define NOTEQ 6
|
||||
#define EQMATCH 7
|
||||
#define NOTEQMATCH 8
|
||||
|
||||
static int exp1(Char ***, int);
|
||||
static int csh_exp2(Char ***, int);
|
||||
static int exp2a(Char ***, int);
|
||||
static int exp2b(Char ***, int);
|
||||
static int exp2c(Char ***, int);
|
||||
static Char *exp3(Char ***, int);
|
||||
static Char *exp3a(Char ***, int);
|
||||
static Char *exp4(Char ***, int);
|
||||
static Char *exp5(Char ***, int);
|
||||
static Char *exp6(Char ***, int);
|
||||
static void evalav(Char **);
|
||||
static int isa(Char *, int);
|
||||
static int egetn(Char *);
|
||||
|
||||
#ifdef EDEBUG
|
||||
static void etracc(char *, Char *, Char ***);
|
||||
static void etraci(char *, int, Char ***);
|
||||
#endif
|
||||
|
||||
int
|
||||
expr(Char ***vp)
|
||||
{
|
||||
return (exp0(vp, 0));
|
||||
}
|
||||
|
||||
int
|
||||
exp0(Char ***vp, int ignore)
|
||||
{
|
||||
int p1;
|
||||
|
||||
p1 = exp1(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp0 p1", p1, vp);
|
||||
#endif
|
||||
if (**vp && eq(**vp, STRor2)) {
|
||||
int p2;
|
||||
|
||||
(*vp)++;
|
||||
p2 = exp0(vp, (ignore & IGNORE) || p1);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp0 p2", p2, vp);
|
||||
#endif
|
||||
return (p1 || p2);
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static int
|
||||
exp1(Char ***vp, int ignore)
|
||||
{
|
||||
int p1;
|
||||
|
||||
p1 = csh_exp2(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp1 p1", p1, vp);
|
||||
#endif
|
||||
if (**vp && eq(**vp, STRand2)) {
|
||||
int p2;
|
||||
|
||||
(*vp)++;
|
||||
p2 = exp1(vp, (ignore & IGNORE) || !p1);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp1 p2", p2, vp);
|
||||
#endif
|
||||
return (p1 && p2);
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static int
|
||||
csh_exp2(Char ***vp, int ignore)
|
||||
{
|
||||
int p1;
|
||||
|
||||
p1 = exp2a(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp3 p1", p1, vp);
|
||||
#endif
|
||||
if (**vp && eq(**vp, STRor)) {
|
||||
int p2;
|
||||
|
||||
(*vp)++;
|
||||
p2 = csh_exp2(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp3 p2", p2, vp);
|
||||
#endif
|
||||
return (p1 | p2);
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static int
|
||||
exp2a(Char ***vp, int ignore)
|
||||
{
|
||||
int p1;
|
||||
|
||||
p1 = exp2b(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp2a p1", p1, vp);
|
||||
#endif
|
||||
if (**vp && eq(**vp, STRcaret)) {
|
||||
int p2;
|
||||
|
||||
(*vp)++;
|
||||
p2 = exp2a(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp2a p2", p2, vp);
|
||||
#endif
|
||||
return (p1 ^ p2);
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static int
|
||||
exp2b(Char ***vp, int ignore)
|
||||
{
|
||||
int p1;
|
||||
|
||||
p1 = exp2c(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp2b p1", p1, vp);
|
||||
#endif
|
||||
if (**vp && eq(**vp, STRand)) {
|
||||
int p2;
|
||||
|
||||
(*vp)++;
|
||||
p2 = exp2b(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp2b p2", p2, vp);
|
||||
#endif
|
||||
return (p1 & p2);
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static int
|
||||
exp2c(Char ***vp, int ignore)
|
||||
{
|
||||
Char *p1, *p2;
|
||||
int i;
|
||||
|
||||
p1 = exp3(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp2c p1", p1, vp);
|
||||
#endif
|
||||
if ((i = isa(**vp, EQOP)) != 0) {
|
||||
(*vp)++;
|
||||
if (i == EQMATCH || i == NOTEQMATCH)
|
||||
ignore |= NOGLOB;
|
||||
p2 = exp3(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp2c p2", p2, vp);
|
||||
#endif
|
||||
if (!(ignore & IGNORE))
|
||||
switch (i) {
|
||||
case EQEQ:
|
||||
i = eq(p1, p2);
|
||||
break;
|
||||
case EQMATCH:
|
||||
i = Gmatch(p1, p2);
|
||||
break;
|
||||
case NOTEQ:
|
||||
i = !eq(p1, p2);
|
||||
break;
|
||||
case NOTEQMATCH:
|
||||
i = !Gmatch(p1, p2);
|
||||
break;
|
||||
}
|
||||
xfree((ptr_t) p1);
|
||||
xfree((ptr_t) p2);
|
||||
return (i);
|
||||
}
|
||||
i = egetn(p1);
|
||||
xfree((ptr_t) p1);
|
||||
return (i);
|
||||
}
|
||||
|
||||
static Char *
|
||||
exp3(Char ***vp, int ignore)
|
||||
{
|
||||
Char *p1, *p2;
|
||||
int i;
|
||||
|
||||
p1 = exp3a(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp3 p1", p1, vp);
|
||||
#endif
|
||||
if ((i = isa(**vp, RELOP)) != 0) {
|
||||
(*vp)++;
|
||||
if (**vp && eq(**vp, STRequal))
|
||||
i |= 1, (*vp)++;
|
||||
p2 = exp3(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp3 p2", p2, vp);
|
||||
#endif
|
||||
if (!(ignore & IGNORE))
|
||||
switch (i) {
|
||||
case GTR:
|
||||
i = egetn(p1) > egetn(p2);
|
||||
break;
|
||||
case GTR | 1:
|
||||
i = egetn(p1) >= egetn(p2);
|
||||
break;
|
||||
case LSS:
|
||||
i = egetn(p1) < egetn(p2);
|
||||
break;
|
||||
case LSS | 1:
|
||||
i = egetn(p1) <= egetn(p2);
|
||||
break;
|
||||
}
|
||||
xfree((ptr_t) p1);
|
||||
xfree((ptr_t) p2);
|
||||
return (putn(i));
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static Char *
|
||||
exp3a(Char ***vp, int ignore)
|
||||
{
|
||||
Char *op, *p1, *p2;
|
||||
int i;
|
||||
|
||||
p1 = exp4(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp3a p1", p1, vp);
|
||||
#endif
|
||||
op = **vp;
|
||||
if (op && any("<>", op[0]) && op[0] == op[1]) {
|
||||
(*vp)++;
|
||||
p2 = exp3a(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp3a p2", p2, vp);
|
||||
#endif
|
||||
if (op[0] == '<')
|
||||
i = egetn(p1) << egetn(p2);
|
||||
else
|
||||
i = egetn(p1) >> egetn(p2);
|
||||
xfree((ptr_t) p1);
|
||||
xfree((ptr_t) p2);
|
||||
return (putn(i));
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static Char *
|
||||
exp4(Char ***vp, int ignore)
|
||||
{
|
||||
Char *p1, *p2;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
p1 = exp5(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp4 p1", p1, vp);
|
||||
#endif
|
||||
if (isa(**vp, ADDOP)) {
|
||||
Char *op;
|
||||
|
||||
op = *(*vp)++;
|
||||
p2 = exp4(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp4 p2", p2, vp);
|
||||
#endif
|
||||
if (!(ignore & IGNORE))
|
||||
switch (op[0]) {
|
||||
case '+':
|
||||
i = egetn(p1) + egetn(p2);
|
||||
break;
|
||||
case '-':
|
||||
i = egetn(p1) - egetn(p2);
|
||||
break;
|
||||
}
|
||||
xfree((ptr_t) p1);
|
||||
xfree((ptr_t) p2);
|
||||
return (putn(i));
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static Char *
|
||||
exp5(Char ***vp, int ignore)
|
||||
{
|
||||
Char *p1, *p2;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
p1 = exp6(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp5 p1", p1, vp);
|
||||
#endif
|
||||
if (isa(**vp, MULOP)) {
|
||||
Char *op;
|
||||
|
||||
op = *(*vp)++;
|
||||
p2 = exp5(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp5 p2", p2, vp);
|
||||
#endif
|
||||
if (!(ignore & IGNORE))
|
||||
switch (op[0]) {
|
||||
case '*':
|
||||
i = egetn(p1) * egetn(p2);
|
||||
break;
|
||||
case '/':
|
||||
i = egetn(p2);
|
||||
if (i == 0)
|
||||
stderror(ERR_DIV0);
|
||||
i = egetn(p1) / i;
|
||||
break;
|
||||
case '%':
|
||||
i = egetn(p2);
|
||||
if (i == 0)
|
||||
stderror(ERR_MOD0);
|
||||
i = egetn(p1) % i;
|
||||
break;
|
||||
}
|
||||
xfree((ptr_t) p1);
|
||||
xfree((ptr_t) p2);
|
||||
return (putn(i));
|
||||
}
|
||||
return (p1);
|
||||
}
|
||||
|
||||
static Char *
|
||||
exp6(Char ***vp, int ignore)
|
||||
{
|
||||
Char *cp, *dp, *ep;
|
||||
int ccode, i;
|
||||
|
||||
i = 0;
|
||||
if (**vp == 0)
|
||||
stderror(ERR_NAME | ERR_EXPRESSION);
|
||||
if (eq(**vp, STRbang)) {
|
||||
(*vp)++;
|
||||
cp = exp6(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp6 ! cp", cp, vp);
|
||||
#endif
|
||||
i = egetn(cp);
|
||||
xfree((ptr_t) cp);
|
||||
return (putn(!i));
|
||||
}
|
||||
if (eq(**vp, STRtilde)) {
|
||||
(*vp)++;
|
||||
cp = exp6(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etracc("exp6 ~ cp", cp, vp);
|
||||
#endif
|
||||
i = egetn(cp);
|
||||
xfree((ptr_t) cp);
|
||||
return (putn(~i));
|
||||
}
|
||||
if (eq(**vp, STRLparen)) {
|
||||
(*vp)++;
|
||||
ccode = exp0(vp, ignore);
|
||||
#ifdef EDEBUG
|
||||
etraci("exp6 () ccode", ccode, vp);
|
||||
#endif
|
||||
if (**vp == 0 || ***vp != ')')
|
||||
stderror(ERR_NAME | ERR_EXPRESSION);
|
||||
(*vp)++;
|
||||
return (putn(ccode));
|
||||
}
|
||||
if (eq(**vp, STRLbrace)) {
|
||||
struct command faket;
|
||||
Char *fakecom[2];
|
||||
Char **v;
|
||||
|
||||
faket.t_dtyp = NODE_COMMAND;
|
||||
faket.t_dflg = 0;
|
||||
faket.t_dcar = faket.t_dcdr = faket.t_dspr = NULL;
|
||||
faket.t_dcom = fakecom;
|
||||
fakecom[0] = STRfakecom;
|
||||
fakecom[1] = NULL;
|
||||
(*vp)++;
|
||||
v = *vp;
|
||||
for (;;) {
|
||||
if (!**vp)
|
||||
stderror(ERR_NAME | ERR_MISSING, '}');
|
||||
if (eq(*(*vp)++, STRRbrace))
|
||||
break;
|
||||
}
|
||||
if (ignore & IGNORE)
|
||||
return (Strsave(STRNULL));
|
||||
psavejob();
|
||||
if (pfork(&faket, -1) == 0) {
|
||||
*--(*vp) = 0;
|
||||
evalav(v);
|
||||
exitstat();
|
||||
}
|
||||
pwait();
|
||||
prestjob();
|
||||
#ifdef EDEBUG
|
||||
etraci("exp6 {} status", egetn(value(STRstatus)), vp);
|
||||
#endif
|
||||
return (putn(egetn(value(STRstatus)) == 0));
|
||||
}
|
||||
if (isa(**vp, ANYOP))
|
||||
return (Strsave(STRNULL));
|
||||
cp = *(*vp)++;
|
||||
if (*cp == '-' && any("erwxfdzopls", cp[1])) {
|
||||
struct stat stb;
|
||||
|
||||
if (cp[2] != '\0')
|
||||
stderror(ERR_NAME | ERR_FILEINQ);
|
||||
/*
|
||||
* Detect missing file names by checking for operator in the file name
|
||||
* position. However, if an operator name appears there, we must make
|
||||
* sure that there's no file by that name (e.g., "/") before announcing
|
||||
* an error. Even this check isn't quite right, since it doesn't take
|
||||
* globbing into account.
|
||||
*/
|
||||
if (isa(**vp, ANYOP) && stat(short2str(**vp), &stb))
|
||||
stderror(ERR_NAME | ERR_FILENAME);
|
||||
|
||||
dp = *(*vp)++;
|
||||
if (ignore & IGNORE)
|
||||
return (Strsave(STRNULL));
|
||||
ep = globone(dp, G_ERROR);
|
||||
switch (cp[1]) {
|
||||
case 'r':
|
||||
i = !access(short2str(ep), R_OK);
|
||||
break;
|
||||
case 'w':
|
||||
i = !access(short2str(ep), W_OK);
|
||||
break;
|
||||
case 'x':
|
||||
i = !access(short2str(ep), X_OK);
|
||||
break;
|
||||
default:
|
||||
if (cp[1] == 'l' ?
|
||||
lstat(short2str(ep), &stb) : stat(short2str(ep), &stb)) {
|
||||
xfree((ptr_t) ep);
|
||||
return (Strsave(STR0));
|
||||
}
|
||||
switch (cp[1]) {
|
||||
case 'd':
|
||||
i = S_ISDIR(stb.st_mode);
|
||||
break;
|
||||
case 'e':
|
||||
i = 1;
|
||||
break;
|
||||
case 'f':
|
||||
i = S_ISREG(stb.st_mode);
|
||||
break;
|
||||
case 'l':
|
||||
#ifdef S_ISLNK
|
||||
i = S_ISLNK(stb.st_mode);
|
||||
#else
|
||||
i = 0;
|
||||
#endif
|
||||
break;
|
||||
case 'o':
|
||||
i = stb.st_uid == (uid_t)uid;
|
||||
break;
|
||||
case 'p':
|
||||
#ifdef S_ISFIFO
|
||||
i = S_ISFIFO(stb.st_mode);
|
||||
#else
|
||||
i = 0;
|
||||
#endif
|
||||
break;
|
||||
case 's':
|
||||
#ifdef S_ISSOCK
|
||||
i = S_ISSOCK(stb.st_mode);
|
||||
#else
|
||||
i = 0;
|
||||
#endif
|
||||
break;
|
||||
case 'z':
|
||||
i = stb.st_size == 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef EDEBUG
|
||||
etraci("exp6 -? i", i, vp);
|
||||
#endif
|
||||
xfree((ptr_t) ep);
|
||||
return (putn(i));
|
||||
}
|
||||
#ifdef EDEBUG
|
||||
etracc("exp6 default", cp, vp);
|
||||
#endif
|
||||
return (ignore & NOGLOB ? Strsave(cp) : globone(cp, G_ERROR));
|
||||
}
|
||||
|
||||
static void
|
||||
evalav(Char **v)
|
||||
{
|
||||
struct wordent *hp, paraml1, *wdp;
|
||||
struct command *t;
|
||||
|
||||
hp = ¶ml1;
|
||||
wdp = hp;
|
||||
set(STRstatus, Strsave(STR0));
|
||||
hp->prev = hp->next = hp;
|
||||
hp->word = STRNULL;
|
||||
while (*v) {
|
||||
struct wordent *new;
|
||||
|
||||
new = (struct wordent *)xcalloc(1, sizeof *wdp);
|
||||
new->prev = wdp;
|
||||
new->next = hp;
|
||||
wdp->next = new;
|
||||
wdp = new;
|
||||
wdp->word = Strsave(*v++);
|
||||
}
|
||||
hp->prev = wdp;
|
||||
alias(¶ml1);
|
||||
t = syntax(paraml1.next, ¶ml1, 0);
|
||||
if (seterr)
|
||||
stderror(ERR_OLD);
|
||||
execute(t, -1, NULL, NULL);
|
||||
freelex(¶ml1), freesyn(t);
|
||||
}
|
||||
|
||||
static int
|
||||
isa(Char *cp, int what)
|
||||
{
|
||||
if (cp == 0)
|
||||
return ((what & RESTOP) != 0);
|
||||
if (cp[1] == 0) {
|
||||
if (what & ADDOP && (*cp == '+' || *cp == '-'))
|
||||
return (1);
|
||||
if (what & MULOP && (*cp == '*' || *cp == '/' || *cp == '%'))
|
||||
return (1);
|
||||
if (what & RESTOP && (*cp == '(' || *cp == ')' || *cp == '!' ||
|
||||
*cp == '~' || *cp == '^' || *cp == '"'))
|
||||
return (1);
|
||||
}
|
||||
else if (cp[2] == 0) {
|
||||
if (what & RESTOP) {
|
||||
if (cp[0] == '|' && cp[1] == '&')
|
||||
return (1);
|
||||
if (cp[0] == '<' && cp[1] == '<')
|
||||
return (1);
|
||||
if (cp[0] == '>' && cp[1] == '>')
|
||||
return (1);
|
||||
}
|
||||
if (what & EQOP) {
|
||||
if (cp[0] == '=') {
|
||||
if (cp[1] == '=')
|
||||
return (EQEQ);
|
||||
if (cp[1] == '~')
|
||||
return (EQMATCH);
|
||||
}
|
||||
else if (cp[0] == '!') {
|
||||
if (cp[1] == '=')
|
||||
return (NOTEQ);
|
||||
if (cp[1] == '~')
|
||||
return (NOTEQMATCH);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (what & RELOP) {
|
||||
if (*cp == '<')
|
||||
return (LSS);
|
||||
if (*cp == '>')
|
||||
return (GTR);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
egetn(Char *cp)
|
||||
{
|
||||
if (*cp && *cp != '-' && !Isdigit(*cp))
|
||||
stderror(ERR_NAME | ERR_EXPRESSION);
|
||||
return (getn(cp));
|
||||
}
|
||||
|
||||
/* Phew! */
|
||||
|
||||
#ifdef EDEBUG
|
||||
static void
|
||||
etraci(char *str, int i, Char ***vp)
|
||||
{
|
||||
(void)fprintf(csherr, "%s=%d\t", str, i);
|
||||
blkpr(csherr, *vp);
|
||||
(void)fprintf(csherr, "\n");
|
||||
}
|
||||
static void
|
||||
etracc(char *str, Char *cp, Char ***vp)
|
||||
{
|
||||
(void)fprintf(csherr, "%s=%s\t", str, vis_str(cp));
|
||||
blkpr(csherr, *vp);
|
||||
(void)fprintf(csherr, "\n");
|
||||
}
|
||||
#endif
|
||||
341
bin/csh/extern.h
Normal file
341
bin/csh/extern.h
Normal file
@@ -0,0 +1,341 @@
|
||||
/* $NetBSD: extern.h,v 1.29 2013/07/16 17:47:43 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 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.
|
||||
*
|
||||
* @(#)extern.h 8.1 (Berkeley) 5/31/93
|
||||
*/
|
||||
|
||||
#ifndef _EXTERN_H_
|
||||
#define _EXTERN_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/*
|
||||
* csh.c
|
||||
*/
|
||||
int gethdir(Char *);
|
||||
void dosource(Char **, struct command *);
|
||||
__dead void exitstat(void);
|
||||
__dead void goodbye(void);
|
||||
void importpath(Char *);
|
||||
void initdesc(void);
|
||||
__dead void pintr(int);
|
||||
__dead void pintr1(int);
|
||||
void printprompt(void);
|
||||
#ifdef EDIT
|
||||
char *printpromptstr(EditLine *);
|
||||
#endif
|
||||
void process(int);
|
||||
void rechist(void);
|
||||
void untty(void);
|
||||
int vis_fputc(int, FILE *);
|
||||
|
||||
#ifdef PROF
|
||||
__dead void done(int);
|
||||
#else
|
||||
__dead void xexit(int);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* dir.c
|
||||
*/
|
||||
void dinit(Char *);
|
||||
void dodirs(Char **, struct command *);
|
||||
Char *dcanon(Char *, Char *);
|
||||
void dtildepr(Char *, Char *);
|
||||
void dtilde(void);
|
||||
void dochngd(Char **, struct command *);
|
||||
Char *dnormalize(Char *);
|
||||
void dopushd(Char **, struct command *);
|
||||
void dopopd(Char **, struct command *);
|
||||
struct directory;
|
||||
void dfree(struct directory *);
|
||||
|
||||
/*
|
||||
* dol.c
|
||||
*/
|
||||
void Dfix(struct command *);
|
||||
Char *Dfix1(Char *);
|
||||
void heredoc(Char *);
|
||||
|
||||
/*
|
||||
* err.c
|
||||
*/
|
||||
void seterror(int, ...);
|
||||
__dead void stderror(int, ...);
|
||||
|
||||
/*
|
||||
* exec.c
|
||||
*/
|
||||
__dead void doexec(Char **, struct command *);
|
||||
void dohash(Char **, struct command *);
|
||||
void dounhash(Char **, struct command *);
|
||||
void dowhich(Char **, struct command *);
|
||||
void execash(Char **, struct command *);
|
||||
void hashstat(Char **, struct command *);
|
||||
void xechoit(Char **);
|
||||
|
||||
/*
|
||||
* exp.c
|
||||
*/
|
||||
int expr(Char ***);
|
||||
int exp0(Char ***, int);
|
||||
|
||||
/*
|
||||
* file.c
|
||||
*/
|
||||
#ifdef FILEC
|
||||
ssize_t tenex(Char *, size_t);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* func.c
|
||||
*/
|
||||
void Setenv(Char *, Char *);
|
||||
void doalias(Char **, struct command *);
|
||||
void dobreak(Char **, struct command *);
|
||||
void docontin(Char **, struct command *);
|
||||
void doecho(Char **, struct command *);
|
||||
void doelse(Char **, struct command *);
|
||||
void doend(Char **, struct command *);
|
||||
void doeval(Char **, struct command *);
|
||||
void doexit(Char **, struct command *);
|
||||
void doforeach(Char **, struct command *);
|
||||
void doglob(Char **, struct command *);
|
||||
void dogoto(Char **, struct command *);
|
||||
void doif(Char **, struct command *);
|
||||
void dolimit(Char **, struct command *);
|
||||
__dead void dologin(Char **, struct command *);
|
||||
__dead void dologout(Char **, struct command *);
|
||||
void donohup(Char **, struct command *);
|
||||
void doonintr(Char **, struct command *);
|
||||
void doprintf(Char **, struct command *);
|
||||
void dorepeat(Char **, struct command *);
|
||||
void dosetenv(Char **, struct command *);
|
||||
void dosuspend(Char **, struct command *);
|
||||
void doswbrk(Char **, struct command *);
|
||||
void doswitch(Char **, struct command *);
|
||||
void doumask(Char **, struct command *);
|
||||
void dounlimit(Char **, struct command *);
|
||||
void dounsetenv(Char **, struct command *);
|
||||
void dowhile(Char **, struct command *);
|
||||
void dozip(Char **, struct command *);
|
||||
void func(struct command *, struct biltins *);
|
||||
struct biltins *isbfunc(struct command *);
|
||||
void prvars(void);
|
||||
void gotolab(Char *);
|
||||
int srchx(Char *);
|
||||
void unalias(Char **, struct command *);
|
||||
void wfree(void);
|
||||
|
||||
/*
|
||||
* glob.c
|
||||
*/
|
||||
Char **dobackp(Char *, int);
|
||||
void Gcat(Char *, Char *);
|
||||
Char *globone(Char *, int);
|
||||
int Gmatch(Char *, Char *);
|
||||
void ginit(void);
|
||||
Char **globall(Char **);
|
||||
void rscan(Char **, void (*)(int));
|
||||
void tglob(Char **);
|
||||
void trim(Char **);
|
||||
#ifdef FILEC
|
||||
int sortscmp(const ptr_t, const ptr_t);
|
||||
#endif /* FILEC */
|
||||
|
||||
/*
|
||||
* hist.c
|
||||
*/
|
||||
void dohist(Char **, struct command *);
|
||||
struct Hist *enthist(int, struct wordent *, int);
|
||||
#ifdef EDIT
|
||||
void loadhist(struct Hist *);
|
||||
#endif
|
||||
void savehist(struct wordent *);
|
||||
|
||||
/*
|
||||
* lex.c
|
||||
*/
|
||||
void addla(Char *);
|
||||
void bseek(struct Ain *);
|
||||
void btell(struct Ain *);
|
||||
void btoeof(void);
|
||||
void copylex(struct wordent *, struct wordent *);
|
||||
Char *domod(Char *, int);
|
||||
void freelex(struct wordent *);
|
||||
int lex(struct wordent *);
|
||||
void prlex(FILE *, struct wordent *);
|
||||
#ifdef EDIT
|
||||
int sprlex(char **, struct wordent *);
|
||||
#endif
|
||||
int readc(int);
|
||||
void settell(void);
|
||||
void unreadc(int);
|
||||
|
||||
/*
|
||||
* misc.c
|
||||
*/
|
||||
int any(const char *, int);
|
||||
Char **blkcat(Char **, Char **);
|
||||
Char **blkcpy(Char **, Char **);
|
||||
Char **blkend(Char **);
|
||||
void blkfree(Char **);
|
||||
int blklen(Char **);
|
||||
void blkpr(FILE *, Char **);
|
||||
Char **blkspl(Char **, Char **);
|
||||
void closem(void);
|
||||
Char **copyblk(Char **);
|
||||
int dcopy(int, int);
|
||||
int dmove(int, int);
|
||||
void donefds(void);
|
||||
Char lastchr(Char *);
|
||||
void lshift(Char **, size_t);
|
||||
int number(Char *);
|
||||
int prefix(Char *, Char *);
|
||||
Char **saveblk(Char **);
|
||||
Char *strip(Char *);
|
||||
Char *quote(Char *);
|
||||
char *strsave(const char *);
|
||||
char *strspl(char *, char *);
|
||||
__dead void udvar(Char *);
|
||||
|
||||
#ifndef SHORT_STRINGS
|
||||
# ifdef NOTUSED
|
||||
char *strstr(const char *, const char *);
|
||||
# endif /* NOTUSED */
|
||||
char *strend(char *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* parse.c
|
||||
*/
|
||||
void alias(struct wordent *);
|
||||
void freesyn(struct command *);
|
||||
struct command *syntax(struct wordent *, struct wordent *, int);
|
||||
|
||||
|
||||
/*
|
||||
* proc.c
|
||||
*/
|
||||
void dobg(Char **, struct command *);
|
||||
void dobg1(Char **, struct command *);
|
||||
void dofg(Char **, struct command *);
|
||||
void dofg1(Char **, struct command *);
|
||||
void dojobs(Char **, struct command *);
|
||||
void dokill(Char **, struct command *);
|
||||
void donotify(Char **, struct command *);
|
||||
void dostop(Char **, struct command *);
|
||||
void dowait(Char **, struct command *);
|
||||
void palloc(int, struct command *);
|
||||
void panystop(int);
|
||||
void pchild(int);
|
||||
void pendjob(void);
|
||||
struct process *pfind(Char *);
|
||||
int pfork(struct command *, int);
|
||||
void pgetty(int, int);
|
||||
void pjwait(struct process *);
|
||||
void pnote(void);
|
||||
void prestjob(void);
|
||||
void psavejob(void);
|
||||
void pstart(struct process *, int);
|
||||
void pwait(void);
|
||||
|
||||
/*
|
||||
* sem.c
|
||||
*/
|
||||
void execute(struct command *, int, int *, int *);
|
||||
void mypipe(int *);
|
||||
|
||||
/*
|
||||
* set.c
|
||||
*/
|
||||
struct varent*adrof1(Char *, struct varent *);
|
||||
void doset(Char **, struct command *);
|
||||
void dolet(Char **, struct command *);
|
||||
Char *putn(int);
|
||||
int getn(Char *);
|
||||
Char *value1(Char *, struct varent *);
|
||||
void set(Char *, Char *);
|
||||
void set1(Char *, Char **, struct varent *);
|
||||
void setq(Char *, Char **, struct varent *);
|
||||
void unset(Char **, struct command *);
|
||||
void unset1(Char *[], struct varent *);
|
||||
void unsetv(Char *);
|
||||
void setNS(Char *);
|
||||
void shift(Char **, struct command *);
|
||||
void plist(struct varent *);
|
||||
|
||||
/*
|
||||
* time.c
|
||||
*/
|
||||
void donice(Char **, struct command *);
|
||||
void dotime(Char **, struct command *);
|
||||
void prusage(FILE *, struct rusage *, struct rusage *, struct timespec *,
|
||||
struct timespec *);
|
||||
void ruadd(struct rusage *, struct rusage *);
|
||||
void settimes(void);
|
||||
void psecs(long);
|
||||
|
||||
/*
|
||||
* alloc.c
|
||||
*/
|
||||
void Free(ptr_t);
|
||||
ptr_t Malloc(size_t);
|
||||
ptr_t Realloc(ptr_t, size_t);
|
||||
ptr_t Calloc(size_t, size_t);
|
||||
|
||||
/*
|
||||
* str.c:
|
||||
*/
|
||||
#ifdef SHORT_STRINGS
|
||||
Char *s_strchr(const Char *, int);
|
||||
Char *s_strrchr(const Char *, int);
|
||||
Char *s_strcat(Char *, const Char *);
|
||||
#ifdef NOTUSED
|
||||
Char *s_strncat(Char *, const Char *, size_t);
|
||||
#endif
|
||||
Char *s_strcpy(Char *, const Char *);
|
||||
Char *s_strncpy(Char *, const Char *, size_t);
|
||||
Char *s_strspl(const Char *, const Char *);
|
||||
size_t s_strlen(const Char *);
|
||||
int s_strcmp(const Char *, const Char *);
|
||||
int s_strncmp(const Char *, const Char *, size_t);
|
||||
Char *s_strsave(const Char *);
|
||||
Char *s_strend(const Char *);
|
||||
Char *s_strstr(const Char *, const Char *);
|
||||
Char *str2short(const char *);
|
||||
Char **blk2short(char **);
|
||||
char *short2str(const Char *);
|
||||
char **short2blk(Char * const *);
|
||||
#endif
|
||||
char *short2qstr(const Char *);
|
||||
char *vis_str(const Char *);
|
||||
|
||||
#endif /* !_EXTERN_H_ */
|
||||
729
bin/csh/file.c
Normal file
729
bin/csh/file.c
Normal file
@@ -0,0 +1,729 @@
|
||||
/* $NetBSD: file.c,v 1.30 2013/07/16 17:47:43 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)file.c 8.2 (Berkeley) 3/19/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: file.c,v 1.30 2013/07/16 17:47:43 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef FILEC
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/tty.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <pwd.h>
|
||||
#include <termios.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef SHORT_STRINGS
|
||||
#include <string.h>
|
||||
#endif /* SHORT_STRINGS */
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
/*
|
||||
* Tenex style file name recognition, .. and more.
|
||||
* History:
|
||||
* Author: Ken Greer, Sept. 1975, CMU.
|
||||
* Finally got around to adding to the Cshell., Ken Greer, Dec. 1981.
|
||||
*/
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define ESC '\033'
|
||||
|
||||
typedef enum {
|
||||
LIST, RECOGNIZE
|
||||
} COMMAND;
|
||||
|
||||
static void setup_tty(int);
|
||||
static void back_to_col_1(void);
|
||||
static int pushback(Char *);
|
||||
static void catn(Char *, Char *, size_t);
|
||||
static void copyn(Char *, Char *, size_t);
|
||||
static Char filetype(Char *, Char *);
|
||||
static void print_by_column(Char *, Char *[], size_t);
|
||||
static Char *tilde(Char *, Char *);
|
||||
static void retype(void);
|
||||
static void beep(void);
|
||||
static void print_recognized_stuff(Char *);
|
||||
static void extract_dir_and_name(Char *, Char *, Char *);
|
||||
static Char *getentry(DIR *, int);
|
||||
static void free_items(Char **, size_t);
|
||||
static size_t tsearch(Char *, COMMAND, size_t);
|
||||
static int recognize(Char *, Char *, size_t, size_t);
|
||||
static int is_prefix(Char *, Char *);
|
||||
static int is_suffix(Char *, Char *);
|
||||
static int ignored(Char *);
|
||||
|
||||
/*
|
||||
* Put this here so the binary can be patched with adb to enable file
|
||||
* completion by default. Filec controls completion, nobeep controls
|
||||
* ringing the terminal bell on incomplete expansions.
|
||||
*/
|
||||
int filec = 0;
|
||||
|
||||
static void
|
||||
setup_tty(int on)
|
||||
{
|
||||
struct termios tchars;
|
||||
|
||||
(void)tcgetattr(SHIN, &tchars);
|
||||
|
||||
if (on) {
|
||||
tchars.c_cc[VEOL] = ESC;
|
||||
if (tchars.c_lflag & ICANON)
|
||||
on = TCSADRAIN;
|
||||
else {
|
||||
tchars.c_lflag |= ICANON;
|
||||
on = TCSAFLUSH;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tchars.c_cc[VEOL] = _POSIX_VDISABLE;
|
||||
on = TCSADRAIN;
|
||||
}
|
||||
|
||||
(void)tcsetattr(SHIN, on, &tchars);
|
||||
}
|
||||
|
||||
/*
|
||||
* Move back to beginning of current line
|
||||
*/
|
||||
static void
|
||||
back_to_col_1(void)
|
||||
{
|
||||
struct termios tty, tty_normal;
|
||||
sigset_t nsigset, osigset;
|
||||
|
||||
sigemptyset(&nsigset);
|
||||
(void)sigaddset(&nsigset, SIGINT);
|
||||
(void)sigprocmask(SIG_BLOCK, &nsigset, &osigset);
|
||||
(void)tcgetattr(SHOUT, &tty);
|
||||
tty_normal = tty;
|
||||
tty.c_iflag &= ~INLCR;
|
||||
tty.c_oflag &= ~ONLCR;
|
||||
(void)tcsetattr(SHOUT, TCSADRAIN, &tty);
|
||||
(void)write(SHOUT, "\r", 1);
|
||||
(void)tcsetattr(SHOUT, TCSADRAIN, &tty_normal);
|
||||
(void)sigprocmask(SIG_SETMASK, &osigset, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Push string contents back into tty queue
|
||||
*/
|
||||
static int
|
||||
pushback(Char *string)
|
||||
{
|
||||
struct termios tty, tty_normal;
|
||||
char buf[64], svchars[sizeof(buf)];
|
||||
sigset_t nsigset, osigset;
|
||||
Char *p;
|
||||
size_t bufidx, i, len_str, nbuf, nsv, onsv, retrycnt;
|
||||
char c;
|
||||
|
||||
nsv = 0;
|
||||
sigemptyset(&nsigset);
|
||||
(void)sigaddset(&nsigset, SIGINT);
|
||||
(void)sigprocmask(SIG_BLOCK, &nsigset, &osigset);
|
||||
(void)tcgetattr(SHOUT, &tty);
|
||||
tty_normal = tty;
|
||||
tty.c_lflag &= ~(ECHOKE | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOCTL);
|
||||
/* FIONREAD works only in noncanonical mode. */
|
||||
tty.c_lflag &= ~ICANON;
|
||||
tty.c_cc[VMIN] = 0;
|
||||
(void)tcsetattr(SHOUT, TCSADRAIN, &tty);
|
||||
|
||||
for (retrycnt = 5; ; retrycnt--) {
|
||||
/*
|
||||
* Push back characters.
|
||||
*/
|
||||
for (p = string; (c = (char)*p) != '\0'; p++)
|
||||
(void)ioctl(SHOUT, TIOCSTI, (ioctl_t) &c);
|
||||
for (i = 0; i < nsv; i++)
|
||||
(void)ioctl(SHOUT, TIOCSTI, (ioctl_t) &svchars[i]);
|
||||
|
||||
if (retrycnt == 0)
|
||||
break; /* give up salvaging characters */
|
||||
|
||||
len_str = (size_t)(p - string);
|
||||
|
||||
if (ioctl(SHOUT, FIONREAD, (ioctl_t) &nbuf) ||
|
||||
nbuf <= len_str + nsv || /* The string fit. */
|
||||
nbuf > sizeof(buf)) /* For future binary compatibility
|
||||
(and safety). */
|
||||
break;
|
||||
|
||||
/*
|
||||
* User has typed characters before the pushback finished.
|
||||
* Salvage the characters.
|
||||
*/
|
||||
|
||||
/* This read() should be in noncanonical mode. */
|
||||
if (read(SHOUT, &buf, nbuf) != (ssize_t)nbuf)
|
||||
continue; /* hangup? */
|
||||
|
||||
onsv = nsv;
|
||||
for (bufidx = 0, i = 0; bufidx < nbuf; bufidx++, i++) {
|
||||
c = buf[bufidx];
|
||||
if ((i < len_str) ? c != (char)string[i] :
|
||||
(i < len_str + onsv) ? c != svchars[i - len_str] : 1) {
|
||||
/* Salvage a character. */
|
||||
if (nsv < (int)(sizeof svchars / sizeof svchars[0])) {
|
||||
svchars[nsv++] = c;
|
||||
i--; /* try this comparison with the next char */
|
||||
} else
|
||||
break; /* too many */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
/*
|
||||
* XXX Is this a bug or a feature of kernel tty driver?
|
||||
*
|
||||
* FIONREAD in canonical mode does not return correct byte count
|
||||
* in tty input queue, but this is required to avoid unwanted echo.
|
||||
*/
|
||||
tty.c_lflag |= ICANON;
|
||||
(void)tcsetattr(SHOUT, TCSADRAIN, &tty);
|
||||
(void)ioctl(SHOUT, FIONREAD, (ioctl_t) &i);
|
||||
#endif
|
||||
(void)tcsetattr(SHOUT, TCSADRAIN, &tty_normal);
|
||||
(void)sigprocmask(SIG_SETMASK, &osigset, NULL);
|
||||
|
||||
return (int)nsv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Concatenate src onto tail of des.
|
||||
* Des is a string whose maximum length is count.
|
||||
* Always null terminate.
|
||||
*/
|
||||
static void
|
||||
catn(Char *des, Char *src, size_t count)
|
||||
{
|
||||
while (count-- > 0 && *des)
|
||||
des++;
|
||||
while (count-- > 0)
|
||||
if ((*des++ = *src++) == 0)
|
||||
return;
|
||||
*des = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* Like strncpy but always leave room for trailing \0
|
||||
* and always null terminate.
|
||||
*/
|
||||
static void
|
||||
copyn(Char *des, Char *src, size_t count)
|
||||
{
|
||||
while (count-- > 0)
|
||||
if ((*des++ = *src++) == 0)
|
||||
return;
|
||||
*des = '\0';
|
||||
}
|
||||
|
||||
static Char
|
||||
filetype(Char *dir, Char *file)
|
||||
{
|
||||
struct stat statb;
|
||||
Char path[MAXPATHLEN];
|
||||
|
||||
catn(Strcpy(path, dir), file, sizeof(path) / sizeof(Char));
|
||||
if (lstat(short2str(path), &statb) == 0) {
|
||||
switch (statb.st_mode & S_IFMT) {
|
||||
case S_IFDIR:
|
||||
return ('/');
|
||||
case S_IFLNK:
|
||||
if (stat(short2str(path), &statb) == 0 && /* follow it out */
|
||||
S_ISDIR(statb.st_mode))
|
||||
return ('>');
|
||||
else
|
||||
return ('@');
|
||||
case S_IFSOCK:
|
||||
return ('=');
|
||||
default:
|
||||
if (statb.st_mode & 0111)
|
||||
return ('*');
|
||||
}
|
||||
}
|
||||
return (' ');
|
||||
}
|
||||
|
||||
static struct winsize win;
|
||||
|
||||
/*
|
||||
* Print sorted down columns
|
||||
*/
|
||||
static void
|
||||
print_by_column(Char *dir, Char *items[], size_t count)
|
||||
{
|
||||
size_t c, columns, i, maxwidth, r, rows;
|
||||
|
||||
maxwidth = 0;
|
||||
|
||||
if (ioctl(SHOUT, TIOCGWINSZ, (ioctl_t) & win) < 0 || win.ws_col == 0)
|
||||
win.ws_col = 80;
|
||||
for (i = 0; i < count; i++)
|
||||
maxwidth = maxwidth > (r = Strlen(items[i])) ? maxwidth : r;
|
||||
maxwidth += 2; /* for the file tag and space */
|
||||
columns = win.ws_col / maxwidth;
|
||||
if (columns == 0)
|
||||
columns = 1;
|
||||
rows = (count + (columns - 1)) / columns;
|
||||
for (r = 0; r < rows; r++) {
|
||||
for (c = 0; c < columns; c++) {
|
||||
i = c * rows + r;
|
||||
if (i < count) {
|
||||
size_t w;
|
||||
|
||||
(void)fprintf(cshout, "%s", vis_str(items[i]));
|
||||
(void)fputc(dir ? filetype(dir, items[i]) : ' ', cshout);
|
||||
if (c < columns - 1) { /* last column? */
|
||||
w = Strlen(items[i]) + 1;
|
||||
for (; w < maxwidth; w++)
|
||||
(void) fputc(' ', cshout);
|
||||
}
|
||||
}
|
||||
}
|
||||
(void)fputc('\r', cshout);
|
||||
(void)fputc('\n', cshout);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Expand file name with possible tilde usage
|
||||
* ~person/mumble
|
||||
* expands to
|
||||
* home_directory_of_person/mumble
|
||||
*/
|
||||
static Char *
|
||||
tilde(Char *new, Char *old)
|
||||
{
|
||||
static Char person[40];
|
||||
struct passwd *pw;
|
||||
Char *o, *p;
|
||||
|
||||
if (old[0] != '~')
|
||||
return (Strcpy(new, old));
|
||||
|
||||
for (p = person, o = &old[1]; *o && *o != '/'; *p++ = *o++)
|
||||
continue;
|
||||
*p = '\0';
|
||||
if (person[0] == '\0')
|
||||
(void)Strcpy(new, value(STRhome));
|
||||
else {
|
||||
pw = getpwnam(short2str(person));
|
||||
if (pw == NULL)
|
||||
return (NULL);
|
||||
(void)Strcpy(new, str2short(pw->pw_dir));
|
||||
}
|
||||
(void)Strcat(new, o);
|
||||
return (new);
|
||||
}
|
||||
|
||||
/*
|
||||
* Cause pending line to be printed
|
||||
*/
|
||||
static void
|
||||
retype(void)
|
||||
{
|
||||
struct termios tty;
|
||||
|
||||
(void)tcgetattr(SHOUT, &tty);
|
||||
tty.c_lflag |= PENDIN;
|
||||
(void)tcsetattr(SHOUT, TCSADRAIN, &tty);
|
||||
}
|
||||
|
||||
static void
|
||||
beep(void)
|
||||
{
|
||||
if (adrof(STRnobeep) == 0)
|
||||
(void)write(SHOUT, "\007", 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Erase that silly ^[ and
|
||||
* print the recognized part of the string
|
||||
*/
|
||||
static void
|
||||
print_recognized_stuff(Char *recognized_part)
|
||||
{
|
||||
/* An optimized erasing of that silly ^[ */
|
||||
(void)fputc('\b', cshout);
|
||||
(void)fputc('\b', cshout);
|
||||
switch (Strlen(recognized_part)) {
|
||||
case 0: /* erase two Characters: ^[ */
|
||||
(void)fputc(' ', cshout);
|
||||
(void)fputc(' ', cshout);
|
||||
(void)fputc('\b', cshout);
|
||||
(void)fputc('\b', cshout);
|
||||
break;
|
||||
case 1: /* overstrike the ^, erase the [ */
|
||||
(void)fprintf(cshout, "%s", vis_str(recognized_part));
|
||||
(void)fputc(' ', cshout);
|
||||
(void)fputc('\b', cshout);
|
||||
break;
|
||||
default: /* overstrike both Characters ^[ */
|
||||
(void)fprintf(cshout, "%s", vis_str(recognized_part));
|
||||
break;
|
||||
}
|
||||
(void)fflush(cshout);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse full path in file into 2 parts: directory and file names
|
||||
* Should leave final slash (/) at end of dir.
|
||||
*/
|
||||
static void
|
||||
extract_dir_and_name(Char *path, Char *dir, Char *name)
|
||||
{
|
||||
Char *p;
|
||||
|
||||
p = Strrchr(path, '/');
|
||||
if (p == NULL) {
|
||||
copyn(name, path, MAXNAMLEN);
|
||||
dir[0] = '\0';
|
||||
}
|
||||
else {
|
||||
copyn(name, ++p, MAXNAMLEN);
|
||||
copyn(dir, path, (size_t)(p - path));
|
||||
}
|
||||
}
|
||||
|
||||
static Char *
|
||||
getentry(DIR *dir_fd, int looking_for_lognames)
|
||||
{
|
||||
struct dirent *dirp;
|
||||
struct passwd *pw;
|
||||
|
||||
if (looking_for_lognames) {
|
||||
if ((pw = getpwent()) == NULL)
|
||||
return (NULL);
|
||||
return (str2short(pw->pw_name));
|
||||
}
|
||||
if ((dirp = readdir(dir_fd)) != NULL)
|
||||
return (str2short(dirp->d_name));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
free_items(Char **items, size_t numitems)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < numitems; i++)
|
||||
xfree((ptr_t) items[i]);
|
||||
xfree((ptr_t) items);
|
||||
}
|
||||
|
||||
#define FREE_ITEMS(items, numitems) { \
|
||||
sigset_t nsigset, osigset;\
|
||||
\
|
||||
sigemptyset(&nsigset);\
|
||||
(void) sigaddset(&nsigset, SIGINT);\
|
||||
(void) sigprocmask(SIG_BLOCK, &nsigset, &osigset);\
|
||||
free_items(items, numitems);\
|
||||
(void) sigprocmask(SIG_SETMASK, &osigset, NULL);\
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a RECOGNIZE or LIST command on string "word".
|
||||
*/
|
||||
static size_t
|
||||
tsearch(Char *word, COMMAND command, size_t max_word_length)
|
||||
{
|
||||
Char dir[MAXPATHLEN + 1], extended_name[MAXNAMLEN + 1];
|
||||
Char name[MAXNAMLEN + 1], tilded_dir[MAXPATHLEN + 1];
|
||||
DIR *dir_fd;
|
||||
Char *entry;
|
||||
int ignoring, looking_for_lognames;
|
||||
size_t name_length, nignored, numitems;
|
||||
Char **items = NULL;
|
||||
size_t maxitems = 0;
|
||||
|
||||
numitems = 0;
|
||||
ignoring = TRUE;
|
||||
nignored = 0;
|
||||
|
||||
looking_for_lognames = (*word == '~') && (Strchr(word, '/') == NULL);
|
||||
if (looking_for_lognames) {
|
||||
(void)setpwent();
|
||||
copyn(name, &word[1], MAXNAMLEN); /* name sans ~ */
|
||||
dir_fd = NULL;
|
||||
}
|
||||
else {
|
||||
extract_dir_and_name(word, dir, name);
|
||||
if (tilde(tilded_dir, dir) == 0)
|
||||
return (0);
|
||||
dir_fd = opendir(*tilded_dir ? short2str(tilded_dir) : ".");
|
||||
if (dir_fd == NULL)
|
||||
return (0);
|
||||
}
|
||||
|
||||
again: /* search for matches */
|
||||
name_length = Strlen(name);
|
||||
for (numitems = 0; (entry = getentry(dir_fd, looking_for_lognames)) != NULL;) {
|
||||
if (!is_prefix(name, entry))
|
||||
continue;
|
||||
/* Don't match . files on null prefix match */
|
||||
if (name_length == 0 && entry[0] == '.' &&
|
||||
!looking_for_lognames)
|
||||
continue;
|
||||
if (command == LIST) {
|
||||
if ((size_t)numitems >= maxitems) {
|
||||
maxitems += 1024;
|
||||
if (items == NULL)
|
||||
items = xmalloc(sizeof(*items) * maxitems);
|
||||
else
|
||||
items = xrealloc((ptr_t) items,
|
||||
sizeof(*items) * maxitems);
|
||||
}
|
||||
items[numitems] = xmalloc((size_t) (Strlen(entry) + 1) *
|
||||
sizeof(Char));
|
||||
copyn(items[numitems], entry, MAXNAMLEN);
|
||||
numitems++;
|
||||
}
|
||||
else { /* RECOGNIZE command */
|
||||
if (ignoring && ignored(entry))
|
||||
nignored++;
|
||||
else if (recognize(extended_name,
|
||||
entry, name_length, ++numitems))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ignoring && numitems == 0 && nignored > 0) {
|
||||
ignoring = FALSE;
|
||||
nignored = 0;
|
||||
if (looking_for_lognames)
|
||||
(void)setpwent();
|
||||
else
|
||||
rewinddir(dir_fd);
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (looking_for_lognames)
|
||||
(void)endpwent();
|
||||
else
|
||||
(void)closedir(dir_fd);
|
||||
if (numitems == 0)
|
||||
return (0);
|
||||
if (command == RECOGNIZE) {
|
||||
if (looking_for_lognames)
|
||||
copyn(word, STRtilde, 1);
|
||||
else
|
||||
/* put back dir part */
|
||||
copyn(word, dir, max_word_length);
|
||||
/* add extended name */
|
||||
catn(word, extended_name, max_word_length);
|
||||
return (numitems);
|
||||
}
|
||||
else { /* LIST */
|
||||
qsort((ptr_t) items, numitems, sizeof(items[0]),
|
||||
(int (*) (const void *, const void *)) sortscmp);
|
||||
print_by_column(looking_for_lognames ? NULL : tilded_dir,
|
||||
items, numitems);
|
||||
if (items != NULL)
|
||||
FREE_ITEMS(items, numitems);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Object: extend what user typed up to an ambiguity.
|
||||
* Algorithm:
|
||||
* On first match, copy full entry (assume it'll be the only match)
|
||||
* On subsequent matches, shorten extended_name to the first
|
||||
* Character mismatch between extended_name and entry.
|
||||
* If we shorten it back to the prefix length, stop searching.
|
||||
*/
|
||||
static int
|
||||
recognize(Char *extended_name, Char *entry, size_t name_length, size_t numitems)
|
||||
{
|
||||
if (numitems == 1) /* 1st match */
|
||||
copyn(extended_name, entry, MAXNAMLEN);
|
||||
else { /* 2nd & subsequent matches */
|
||||
Char *ent, *x;
|
||||
size_t len = 0;
|
||||
|
||||
x = extended_name;
|
||||
for (ent = entry; *x && *x == *ent++; x++, len++)
|
||||
continue;
|
||||
*x = '\0'; /* Shorten at 1st Char diff */
|
||||
if (len == name_length) /* Ambiguous to prefix? */
|
||||
return (-1); /* So stop now and save time */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if check matches initial Chars in template.
|
||||
* This differs from PWB imatch in that if check is null
|
||||
* it matches anything.
|
||||
*/
|
||||
static int
|
||||
is_prefix(Char *check, Char *template)
|
||||
{
|
||||
do
|
||||
if (*check == 0)
|
||||
return (TRUE);
|
||||
while (*check++ == *template++);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if the Chars in template appear at the
|
||||
* end of check, I.e., are its suffix.
|
||||
*/
|
||||
static int
|
||||
is_suffix(Char *check, Char *template)
|
||||
{
|
||||
Char *c, *t;
|
||||
|
||||
for (c = check; *c++;)
|
||||
continue;
|
||||
for (t = template; *t++;)
|
||||
continue;
|
||||
for (;;) {
|
||||
if (t == template)
|
||||
return 1;
|
||||
if (c == check || *--t != *--c)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t
|
||||
tenex(Char *inputline, size_t inputline_size)
|
||||
{
|
||||
char tinputline[BUFSIZE];
|
||||
ssize_t num_read;
|
||||
size_t numitems;
|
||||
|
||||
setup_tty(ON);
|
||||
|
||||
while ((num_read = read(SHIN, tinputline, BUFSIZE)) > 0) {
|
||||
size_t i, nr = (size_t) num_read;
|
||||
|
||||
|
||||
static Char delims[] = {' ', '\'', '"', '\t', ';', '&', '<',
|
||||
'>', '(', ')', '|', '^', '%', '\0'};
|
||||
Char *str_end, *word_start, last_Char, should_retype;
|
||||
size_t space_left;
|
||||
COMMAND command;
|
||||
|
||||
for (i = 0; i < nr; i++)
|
||||
inputline[i] = (unsigned char) tinputline[i];
|
||||
last_Char = inputline[nr - 1] & ASCII;
|
||||
|
||||
if (last_Char == '\n' || nr == inputline_size)
|
||||
break;
|
||||
command = (last_Char == ESC) ? RECOGNIZE : LIST;
|
||||
if (command == LIST)
|
||||
(void)fputc('\n', cshout);
|
||||
str_end = &inputline[nr];
|
||||
if (last_Char == ESC)
|
||||
--str_end; /* wipeout trailing cmd Char */
|
||||
*str_end = '\0';
|
||||
/*
|
||||
* Find LAST occurence of a delimiter in the inputline. The word start
|
||||
* is one Character past it.
|
||||
*/
|
||||
for (word_start = str_end; word_start > inputline; --word_start)
|
||||
if (Strchr(delims, word_start[-1]))
|
||||
break;
|
||||
space_left = inputline_size - (size_t)(word_start - inputline) - 1;
|
||||
numitems = tsearch(word_start, command, space_left);
|
||||
|
||||
if (command == RECOGNIZE) {
|
||||
/* print from str_end on */
|
||||
print_recognized_stuff(str_end);
|
||||
if (numitems != 1) /* Beep = No match/ambiguous */
|
||||
beep();
|
||||
}
|
||||
|
||||
/*
|
||||
* Tabs in the input line cause trouble after a pushback. tty driver
|
||||
* won't backspace over them because column positions are now
|
||||
* incorrect. This is solved by retyping over current line.
|
||||
*/
|
||||
should_retype = FALSE;
|
||||
if (Strchr(inputline, '\t')) { /* tab Char in input line? */
|
||||
back_to_col_1();
|
||||
should_retype = TRUE;
|
||||
}
|
||||
if (command == LIST) /* Always retype after a LIST */
|
||||
should_retype = TRUE;
|
||||
if (pushback(inputline))
|
||||
should_retype = TRUE;
|
||||
if (should_retype) {
|
||||
if (command == RECOGNIZE)
|
||||
(void) fputc('\n', cshout);
|
||||
printprompt();
|
||||
}
|
||||
if (should_retype)
|
||||
retype();
|
||||
}
|
||||
setup_tty(OFF);
|
||||
return num_read;
|
||||
}
|
||||
|
||||
static int
|
||||
ignored(Char *entry)
|
||||
{
|
||||
struct varent *vp;
|
||||
Char **cp;
|
||||
|
||||
if ((vp = adrof(STRfignore)) == NULL || (cp = vp->vec) == NULL)
|
||||
return (FALSE);
|
||||
for (; *cp != NULL; cp++)
|
||||
if (is_suffix(entry, *cp))
|
||||
return (TRUE);
|
||||
return (FALSE);
|
||||
}
|
||||
#endif /* FILEC */
|
||||
1456
bin/csh/func.c
Normal file
1456
bin/csh/func.c
Normal file
File diff suppressed because it is too large
Load Diff
923
bin/csh/glob.c
Normal file
923
bin/csh/glob.c
Normal file
@@ -0,0 +1,923 @@
|
||||
/* $NetBSD: glob.c,v 1.27 2013/07/16 17:47:43 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)glob.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: glob.c,v 1.27 2013/07/16 17:47:43 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <glob.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
static int noglob;
|
||||
static int gargsiz, pargsiz;
|
||||
|
||||
/*
|
||||
* Values for gflag
|
||||
*/
|
||||
#define G_NONE 0 /* No globbing needed */
|
||||
#define G_GLOB 1 /* string contains *?[] characters */
|
||||
#define G_CSH 2 /* string contains ~`{ characters */
|
||||
|
||||
#define GLOBSPACE 100 /* Alloc increment */
|
||||
|
||||
#define LBRC '{'
|
||||
#define RBRC '}'
|
||||
#define LBRK '['
|
||||
#define RBRK ']'
|
||||
#define EOS '\0'
|
||||
|
||||
Char **gargv = NULL;
|
||||
Char **pargv = NULL;
|
||||
long gargc = 0;
|
||||
long pargc = 0;
|
||||
|
||||
/*
|
||||
* globbing is now done in two stages. In the first pass we expand
|
||||
* csh globbing idioms ~`{ and then we proceed doing the normal
|
||||
* globbing if needed ?*[
|
||||
*
|
||||
* Csh type globbing is handled in globexpand() and the rest is
|
||||
* handled in glob() which is part of the 4.4BSD libc.
|
||||
*
|
||||
*/
|
||||
static Char *globtilde(Char **, Char *);
|
||||
static Char *handleone(Char *, Char **, int);
|
||||
static Char **libglob(Char **);
|
||||
static Char **globexpand(Char **);
|
||||
static int globbrace(Char *, Char *, Char ***);
|
||||
static void expbrace(Char ***, Char ***, size_t);
|
||||
static int pmatch(Char *, Char *);
|
||||
static void pword(void);
|
||||
static void psave(int);
|
||||
static void backeval(Char *, int);
|
||||
|
||||
static Char *
|
||||
globtilde(Char **nv, Char *s)
|
||||
{
|
||||
Char gbuf[MAXPATHLEN], *b, *e, *gstart, *u;
|
||||
|
||||
gstart = gbuf;
|
||||
*gstart++ = *s++;
|
||||
u = s;
|
||||
for (b = gstart, e = &gbuf[MAXPATHLEN - 1];
|
||||
*s && *s != '/' && *s != ':' && b < e;
|
||||
*b++ = *s++)
|
||||
continue;
|
||||
*b = EOS;
|
||||
if (gethdir(gstart)) {
|
||||
blkfree(nv);
|
||||
if (*gstart)
|
||||
stderror(ERR_UNKUSER, vis_str(gstart));
|
||||
else
|
||||
stderror(ERR_NOHOME);
|
||||
}
|
||||
b = &gstart[Strlen(gstart)];
|
||||
while (*s)
|
||||
*b++ = *s++;
|
||||
*b = EOS;
|
||||
--u;
|
||||
xfree((ptr_t) u);
|
||||
return (Strsave(gstart));
|
||||
}
|
||||
|
||||
static int
|
||||
globbrace(Char *s, Char *p, Char ***bl)
|
||||
{
|
||||
Char gbuf[MAXPATHLEN];
|
||||
Char *lm, *pe, *pl, *pm, **nv, **vl;
|
||||
int i, len, size;
|
||||
|
||||
size = GLOBSPACE;
|
||||
nv = vl = xmalloc(sizeof(Char *) * (size_t)size);
|
||||
*vl = NULL;
|
||||
len = 0;
|
||||
/* copy part up to the brace */
|
||||
for (lm = gbuf, p = s; *p != LBRC; *lm++ = *p++)
|
||||
continue;
|
||||
|
||||
/* check for balanced braces */
|
||||
for (i = 0, pe = ++p; *pe; pe++)
|
||||
if (*pe == LBRK) {
|
||||
/* Ignore everything between [] */
|
||||
for (++pe; *pe != RBRK && *pe != EOS; pe++)
|
||||
continue;
|
||||
if (*pe == EOS) {
|
||||
blkfree(nv);
|
||||
return (-RBRK);
|
||||
}
|
||||
}
|
||||
else if (*pe == LBRC)
|
||||
i++;
|
||||
else if (*pe == RBRC) {
|
||||
if (i == 0)
|
||||
break;
|
||||
i--;
|
||||
}
|
||||
|
||||
if (i != 0 || *pe == '\0') {
|
||||
blkfree(nv);
|
||||
return (-RBRC);
|
||||
}
|
||||
|
||||
for (i = 0, pl = pm = p; pm <= pe; pm++)
|
||||
switch (*pm) {
|
||||
case LBRK:
|
||||
for (++pm; *pm != RBRK && *pm != EOS; pm++)
|
||||
continue;
|
||||
if (*pm == EOS) {
|
||||
*vl = NULL;
|
||||
blkfree(nv);
|
||||
return (-RBRK);
|
||||
}
|
||||
break;
|
||||
case LBRC:
|
||||
i++;
|
||||
break;
|
||||
case RBRC:
|
||||
if (i) {
|
||||
i--;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case ',':
|
||||
if (i && *pm == ',')
|
||||
break;
|
||||
else {
|
||||
Char savec = *pm;
|
||||
|
||||
*pm = EOS;
|
||||
(void)Strcpy(lm, pl);
|
||||
(void)Strcat(gbuf, pe + 1);
|
||||
*pm = savec;
|
||||
*vl++ = Strsave(gbuf);
|
||||
len++;
|
||||
pl = pm + 1;
|
||||
if (vl == &nv[size]) {
|
||||
size += GLOBSPACE;
|
||||
nv = (Char **)xrealloc((ptr_t) nv,
|
||||
(size_t)size * sizeof(Char *));
|
||||
vl = &nv[size - GLOBSPACE];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*vl = NULL;
|
||||
*bl = nv;
|
||||
return (len);
|
||||
}
|
||||
|
||||
static void
|
||||
expbrace(Char ***nvp, Char ***elp, size_t size)
|
||||
{
|
||||
Char **ex, **nv, *s, **vl;
|
||||
|
||||
vl = nv = *nvp;
|
||||
if (elp != NULL)
|
||||
ex = *elp;
|
||||
else
|
||||
for (ex = vl; *ex; ex++)
|
||||
continue;
|
||||
|
||||
for (s = *vl; s; s = *++vl) {
|
||||
Char *b, **bp, **vp;
|
||||
|
||||
/* leave {} untouched for find */
|
||||
if (s[0] == '{' && (s[1] == '\0' || (s[1] == '}' && s[2] == '\0')))
|
||||
continue;
|
||||
if ((b = Strchr(s, '{')) != NULL) {
|
||||
Char **bl;
|
||||
int len;
|
||||
|
||||
if ((len = globbrace(s, b, &bl)) < 0) {
|
||||
xfree((ptr_t)nv);
|
||||
stderror(ERR_MISSING, -len);
|
||||
}
|
||||
xfree((ptr_t) s);
|
||||
if (len == 1) {
|
||||
*vl-- = *bl;
|
||||
xfree((ptr_t) bl);
|
||||
continue;
|
||||
}
|
||||
len = blklen(bl);
|
||||
if (&ex[len] >= &nv[size]) {
|
||||
ptrdiff_t l, e;
|
||||
|
||||
l = &ex[len] - &nv[size];
|
||||
size += (size_t)(GLOBSPACE > l ? GLOBSPACE : l);
|
||||
l = vl - nv;
|
||||
e = ex - nv;
|
||||
nv = (Char **)xrealloc((ptr_t)nv,
|
||||
(size_t)size * sizeof(Char *));
|
||||
vl = nv + l;
|
||||
ex = nv + e;
|
||||
}
|
||||
vp = vl--;
|
||||
*vp = *bl;
|
||||
len--;
|
||||
for (bp = ex; bp != vp; bp--)
|
||||
bp[len] = *bp;
|
||||
ex += len;
|
||||
vp++;
|
||||
for (bp = bl + 1; *bp; *vp++ = *bp++)
|
||||
continue;
|
||||
xfree((ptr_t)bl);
|
||||
}
|
||||
|
||||
}
|
||||
if (elp != NULL)
|
||||
*elp = ex;
|
||||
*nvp = nv;
|
||||
}
|
||||
|
||||
static Char **
|
||||
globexpand(Char **v)
|
||||
{
|
||||
Char **ex, **nv, *s, **vl;
|
||||
size_t size;
|
||||
|
||||
size = GLOBSPACE;
|
||||
nv = vl = xmalloc(sizeof(Char *) * size);
|
||||
*vl = NULL;
|
||||
|
||||
/*
|
||||
* Step 1: expand backquotes.
|
||||
*/
|
||||
while ((s = *v++) != NULL) {
|
||||
if (Strchr(s, '`')) {
|
||||
int i;
|
||||
|
||||
(void) dobackp(s, 0);
|
||||
for (i = 0; i < pargc; i++) {
|
||||
*vl++ = pargv[i];
|
||||
if (vl == &nv[size]) {
|
||||
size += GLOBSPACE;
|
||||
nv = (Char **)xrealloc((ptr_t) nv,
|
||||
(size_t)size * sizeof(Char *));
|
||||
vl = &nv[size - GLOBSPACE];
|
||||
}
|
||||
}
|
||||
xfree((ptr_t)pargv);
|
||||
pargv = NULL;
|
||||
}
|
||||
else {
|
||||
*vl++ = Strsave(s);
|
||||
if (vl == &nv[size]) {
|
||||
size += GLOBSPACE;
|
||||
nv = (Char **)xrealloc((ptr_t)nv,
|
||||
size * sizeof(Char *));
|
||||
vl = &nv[size - GLOBSPACE];
|
||||
}
|
||||
}
|
||||
}
|
||||
*vl = NULL;
|
||||
|
||||
if (noglob)
|
||||
return (nv);
|
||||
|
||||
/*
|
||||
* Step 2: expand braces
|
||||
*/
|
||||
ex = vl;
|
||||
expbrace(&nv, &ex, size);
|
||||
|
||||
/*
|
||||
* Step 3: expand ~
|
||||
*/
|
||||
vl = nv;
|
||||
for (s = *vl; s; s = *++vl)
|
||||
if (*s == '~')
|
||||
*vl = globtilde(nv, s);
|
||||
vl = nv;
|
||||
return (vl);
|
||||
}
|
||||
|
||||
static Char *
|
||||
handleone(Char *str, Char **vl, int action)
|
||||
{
|
||||
Char *cp, **vlp;
|
||||
|
||||
vlp = vl;
|
||||
switch (action) {
|
||||
case G_ERROR:
|
||||
setname(vis_str(str));
|
||||
blkfree(vl);
|
||||
stderror(ERR_NAME | ERR_AMBIG);
|
||||
/* NOTREACHED */
|
||||
case G_APPEND:
|
||||
trim(vlp);
|
||||
str = Strsave(*vlp++);
|
||||
do {
|
||||
cp = Strspl(str, STRspace);
|
||||
xfree((ptr_t)str);
|
||||
str = Strspl(cp, *vlp);
|
||||
xfree((ptr_t)cp);
|
||||
}
|
||||
while (*++vlp);
|
||||
blkfree(vl);
|
||||
break;
|
||||
case G_IGNORE:
|
||||
str = Strsave(strip(*vlp));
|
||||
blkfree(vl);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (str);
|
||||
}
|
||||
|
||||
static Char **
|
||||
libglob(Char **vl)
|
||||
{
|
||||
glob_t globv;
|
||||
char *ptr;
|
||||
int gflgs, magic, match, nonomatch;
|
||||
|
||||
gflgs = GLOB_NOMAGIC;
|
||||
magic = 0;
|
||||
match = 0;
|
||||
nonomatch = adrof(STRnonomatch) != 0;
|
||||
|
||||
if (!vl || !vl[0])
|
||||
return (vl);
|
||||
|
||||
globv.gl_offs = 0;
|
||||
globv.gl_pathv = 0;
|
||||
globv.gl_pathc = 0;
|
||||
|
||||
if (nonomatch)
|
||||
gflgs |= GLOB_NOCHECK;
|
||||
|
||||
do {
|
||||
ptr = short2qstr(*vl);
|
||||
switch (glob(ptr, gflgs, 0, &globv)) {
|
||||
case GLOB_ABORTED:
|
||||
setname(vis_str(*vl));
|
||||
stderror(ERR_NAME | ERR_GLOB);
|
||||
/* NOTREACHED */
|
||||
case GLOB_NOSPACE:
|
||||
stderror(ERR_NOMEM);
|
||||
/* NOTREACHED */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (globv.gl_flags & GLOB_MAGCHAR) {
|
||||
match |= (globv.gl_matchc != 0);
|
||||
magic = 1;
|
||||
}
|
||||
gflgs |= GLOB_APPEND;
|
||||
}
|
||||
while (*++vl);
|
||||
vl = (globv.gl_pathc == 0 || (magic && !match && !nonomatch)) ?
|
||||
NULL : blk2short(globv.gl_pathv);
|
||||
globfree(&globv);
|
||||
return (vl);
|
||||
}
|
||||
|
||||
Char *
|
||||
globone(Char *str, int action)
|
||||
{
|
||||
Char *v[2], **vl, **vo;
|
||||
int gflg;
|
||||
|
||||
noglob = adrof(STRnoglob) != 0;
|
||||
gflag = 0;
|
||||
v[0] = str;
|
||||
v[1] = 0;
|
||||
tglob(v);
|
||||
gflg = gflag;
|
||||
if (gflg == G_NONE)
|
||||
return (strip(Strsave(str)));
|
||||
|
||||
if (gflg & G_CSH) {
|
||||
/*
|
||||
* Expand back-quote, tilde and brace
|
||||
*/
|
||||
vo = globexpand(v);
|
||||
if (noglob || (gflg & G_GLOB) == 0) {
|
||||
if (vo[0] == NULL) {
|
||||
xfree((ptr_t)vo);
|
||||
return (Strsave(STRNULL));
|
||||
}
|
||||
if (vo[1] != NULL)
|
||||
return (handleone(str, vo, action));
|
||||
else {
|
||||
str = strip(vo[0]);
|
||||
xfree((ptr_t) vo);
|
||||
return (str);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (noglob || (gflg & G_GLOB) == 0)
|
||||
return (strip(Strsave(str)));
|
||||
else
|
||||
vo = v;
|
||||
|
||||
vl = libglob(vo);
|
||||
if ((gflg & G_CSH) && vl != vo)
|
||||
blkfree(vo);
|
||||
if (vl == NULL) {
|
||||
setname(vis_str(str));
|
||||
stderror(ERR_NAME | ERR_NOMATCH);
|
||||
}
|
||||
if (vl[0] == NULL) {
|
||||
xfree((ptr_t)vl);
|
||||
return (Strsave(STRNULL));
|
||||
}
|
||||
if (vl[1] != NULL)
|
||||
return (handleone(str, vl, action));
|
||||
else {
|
||||
str = strip(*vl);
|
||||
xfree((ptr_t)vl);
|
||||
return (str);
|
||||
}
|
||||
}
|
||||
|
||||
Char **
|
||||
globall(Char **v)
|
||||
{
|
||||
Char **vl, **vo;
|
||||
int gflg;
|
||||
|
||||
gflg = gflag;
|
||||
if (!v || !v[0]) {
|
||||
gargv = saveblk(v);
|
||||
gargc = blklen(gargv);
|
||||
return (gargv);
|
||||
}
|
||||
|
||||
noglob = adrof(STRnoglob) != 0;
|
||||
|
||||
if (gflg & G_CSH)
|
||||
/*
|
||||
* Expand back-quote, tilde and brace
|
||||
*/
|
||||
vl = vo = globexpand(v);
|
||||
else
|
||||
vl = vo = saveblk(v);
|
||||
|
||||
if (!noglob && (gflg & G_GLOB)) {
|
||||
vl = libglob(vo);
|
||||
if ((gflg & G_CSH) && vl != vo)
|
||||
blkfree(vo);
|
||||
}
|
||||
else
|
||||
trim(vl);
|
||||
|
||||
gargc = vl ? blklen(vl) : 0;
|
||||
return (gargv = vl);
|
||||
}
|
||||
|
||||
void
|
||||
ginit(void)
|
||||
{
|
||||
gargsiz = GLOBSPACE;
|
||||
gargv = xmalloc(sizeof(Char *) * (size_t)gargsiz);
|
||||
gargv[0] = 0;
|
||||
gargc = 0;
|
||||
}
|
||||
|
||||
void
|
||||
rscan(Char **t, void (*f)(int))
|
||||
{
|
||||
Char *p;
|
||||
|
||||
while ((p = *t++) != NULL)
|
||||
while (*p)
|
||||
(*f) (*p++);
|
||||
}
|
||||
|
||||
void
|
||||
trim(Char **t)
|
||||
{
|
||||
Char *p;
|
||||
|
||||
while ((p = *t++) != NULL)
|
||||
while (*p)
|
||||
*p++ &= TRIM;
|
||||
}
|
||||
|
||||
void
|
||||
tglob(Char **t)
|
||||
{
|
||||
Char *p, c;
|
||||
|
||||
while ((p = *t++) != NULL) {
|
||||
if (*p == '~' || *p == '=')
|
||||
gflag |= G_CSH;
|
||||
else if (*p == '{' &&
|
||||
(p[1] == '\0' || (p[1] == '}' && p[2] == '\0')))
|
||||
continue;
|
||||
while ((c = *p++) != '\0') {
|
||||
/*
|
||||
* eat everything inside the matching backquotes
|
||||
*/
|
||||
if (c == '`') {
|
||||
gflag |= G_CSH;
|
||||
while (*p && *p != '`')
|
||||
if (*p++ == '\\') {
|
||||
if (*p) /* Quoted chars */
|
||||
p++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (*p) /* The matching ` */
|
||||
p++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
else if (c == '{')
|
||||
gflag |= G_CSH;
|
||||
else if (isglob(c))
|
||||
gflag |= G_GLOB;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Command substitute cp. If literal, then this is a substitution from a
|
||||
* << redirection, and so we should not crunch blanks and tabs, separating
|
||||
* words only at newlines.
|
||||
*/
|
||||
Char **
|
||||
dobackp(Char *cp, int literal)
|
||||
{
|
||||
Char word[MAXPATHLEN], *ep, *lp, *rp;
|
||||
|
||||
if (pargv) {
|
||||
#ifdef notdef
|
||||
abort();
|
||||
#endif
|
||||
blkfree(pargv);
|
||||
}
|
||||
pargsiz = GLOBSPACE;
|
||||
pargv = xmalloc(sizeof(Char *) * (size_t)pargsiz);
|
||||
pargv[0] = NULL;
|
||||
pargcp = pargs = word;
|
||||
pargc = 0;
|
||||
pnleft = MAXPATHLEN - 4;
|
||||
for (;;) {
|
||||
for (lp = cp; *lp != '`'; lp++) {
|
||||
if (*lp == 0) {
|
||||
if (pargcp != pargs)
|
||||
pword();
|
||||
return (pargv);
|
||||
}
|
||||
psave(*lp);
|
||||
}
|
||||
lp++;
|
||||
for (rp = lp; *rp && *rp != '`'; rp++)
|
||||
if (*rp == '\\') {
|
||||
rp++;
|
||||
if (!*rp)
|
||||
goto oops;
|
||||
}
|
||||
if (!*rp) {
|
||||
oops:
|
||||
stderror(ERR_UNMATCHED, '`');
|
||||
}
|
||||
ep = Strsave(lp);
|
||||
ep[rp - lp] = 0;
|
||||
backeval(ep, literal);
|
||||
cp = rp + 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
backeval(Char *cp, int literal)
|
||||
{
|
||||
struct command faket;
|
||||
char tibuf[BUFSIZE];
|
||||
Char ibuf[BUFSIZE], *fakecom[2], *ip;
|
||||
int pvec[2], c, quoted;
|
||||
ssize_t icnt;
|
||||
int hadnl;
|
||||
|
||||
hadnl = 0;
|
||||
icnt = 0;
|
||||
quoted = (literal || (cp[0] & QUOTE)) ? QUOTE : 0;
|
||||
faket.t_dtyp = NODE_COMMAND;
|
||||
faket.t_dflg = 0;
|
||||
faket.t_dlef = 0;
|
||||
faket.t_drit = 0;
|
||||
faket.t_dspr = 0;
|
||||
faket.t_dcom = fakecom;
|
||||
fakecom[0] = STRfakecom1;
|
||||
fakecom[1] = 0;
|
||||
|
||||
/*
|
||||
* We do the psave job to temporarily change the current job so that the
|
||||
* following fork is considered a separate job. This is so that when
|
||||
* backquotes are used in a builtin function that calls glob the "current
|
||||
* job" is not corrupted. We only need one level of pushed jobs as long as
|
||||
* we are sure to fork here.
|
||||
*/
|
||||
psavejob();
|
||||
|
||||
/*
|
||||
* It would be nicer if we could integrate this redirection more with the
|
||||
* routines in sh.sem.c by doing a fake execute on a builtin function that
|
||||
* was piped out.
|
||||
*/
|
||||
mypipe(pvec);
|
||||
if (pfork(&faket, -1) == 0) {
|
||||
struct wordent fparaml;
|
||||
struct command *t;
|
||||
|
||||
(void)close(pvec[0]);
|
||||
(void)dmove(pvec[1], 1);
|
||||
(void)dmove(SHERR, 2);
|
||||
initdesc();
|
||||
/*
|
||||
* Bugfix for nested backquotes by Michael Greim <greim@sbsvax.UUCP>,
|
||||
* posted to comp.bugs.4bsd 12 Sep. 1989.
|
||||
*/
|
||||
if (pargv) /* mg, 21.dec.88 */
|
||||
blkfree(pargv), pargv = 0, pargsiz = 0;
|
||||
/* mg, 21.dec.88 */
|
||||
arginp = cp;
|
||||
for (arginp = cp; *cp; cp++) {
|
||||
*cp &= TRIM;
|
||||
if (*cp == '\n' || *cp == '\r')
|
||||
*cp = ';';
|
||||
}
|
||||
|
||||
/*
|
||||
* In the child ``forget'' everything about current aliases or
|
||||
* eval vectors.
|
||||
*/
|
||||
alvec = NULL;
|
||||
evalvec = NULL;
|
||||
alvecp = NULL;
|
||||
evalp = NULL;
|
||||
(void) lex(&fparaml);
|
||||
if (seterr)
|
||||
stderror(ERR_OLD);
|
||||
alias(&fparaml);
|
||||
t = syntax(fparaml.next, &fparaml, 0);
|
||||
if (seterr)
|
||||
stderror(ERR_OLD);
|
||||
if (t)
|
||||
t->t_dflg |= F_NOFORK;
|
||||
(void)signal(SIGTSTP, SIG_IGN);
|
||||
(void)signal(SIGTTIN, SIG_IGN);
|
||||
(void)signal(SIGTTOU, SIG_IGN);
|
||||
execute(t, -1, NULL, NULL);
|
||||
exitstat();
|
||||
}
|
||||
xfree((ptr_t)cp);
|
||||
(void)close(pvec[1]);
|
||||
c = 0;
|
||||
ip = NULL;
|
||||
do {
|
||||
int cnt;
|
||||
|
||||
cnt = 0;
|
||||
|
||||
for (;;) {
|
||||
if (icnt == 0) {
|
||||
int i;
|
||||
|
||||
ip = ibuf;
|
||||
do
|
||||
icnt = read(pvec[0], tibuf, BUFSIZE);
|
||||
while (icnt == -1 && errno == EINTR);
|
||||
if (icnt <= 0) {
|
||||
c = -1;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < icnt; i++)
|
||||
ip[i] = (unsigned char) tibuf[i];
|
||||
}
|
||||
if (hadnl)
|
||||
break;
|
||||
--icnt;
|
||||
c = (*ip++ & TRIM);
|
||||
if (c == 0)
|
||||
break;
|
||||
if (c == '\n') {
|
||||
/*
|
||||
* Continue around the loop one more time, so that we can eat
|
||||
* the last newline without terminating this word.
|
||||
*/
|
||||
hadnl = 1;
|
||||
continue;
|
||||
}
|
||||
if (!quoted && (c == ' ' || c == '\t'))
|
||||
break;
|
||||
cnt++;
|
||||
psave(c | quoted);
|
||||
}
|
||||
/*
|
||||
* Unless at end-of-file, we will form a new word here if there were
|
||||
* characters in the word, or in any case when we take text literally.
|
||||
* If we didn't make empty words here when literal was set then we
|
||||
* would lose blank lines.
|
||||
*/
|
||||
if (c != -1 && (cnt || literal))
|
||||
pword();
|
||||
hadnl = 0;
|
||||
} while (c >= 0);
|
||||
(void)close(pvec[0]);
|
||||
pwait();
|
||||
prestjob();
|
||||
}
|
||||
|
||||
static void
|
||||
psave(int c)
|
||||
{
|
||||
if (--pnleft <= 0)
|
||||
stderror(ERR_WTOOLONG);
|
||||
*pargcp++ = (Char)c;
|
||||
}
|
||||
|
||||
static void
|
||||
pword(void)
|
||||
{
|
||||
psave(0);
|
||||
if (pargc == pargsiz - 1) {
|
||||
pargsiz += GLOBSPACE;
|
||||
pargv = (Char **)xrealloc((ptr_t)pargv,
|
||||
(size_t)pargsiz * sizeof(Char *));
|
||||
}
|
||||
pargv[pargc++] = Strsave(pargs);
|
||||
pargv[pargc] = NULL;
|
||||
pargcp = pargs;
|
||||
pnleft = MAXPATHLEN - 4;
|
||||
}
|
||||
|
||||
int
|
||||
Gmatch(Char *string, Char *pattern)
|
||||
{
|
||||
Char **blk, **p;
|
||||
int gpol, gres;
|
||||
|
||||
gpol = 1;
|
||||
gres = 0;
|
||||
|
||||
if (*pattern == '^') {
|
||||
gpol = 0;
|
||||
pattern++;
|
||||
}
|
||||
|
||||
blk = xmalloc(GLOBSPACE * sizeof(Char *));
|
||||
blk[0] = Strsave(pattern);
|
||||
blk[1] = NULL;
|
||||
|
||||
expbrace(&blk, NULL, GLOBSPACE);
|
||||
|
||||
for (p = blk; *p; p++)
|
||||
gres |= pmatch(string, *p);
|
||||
|
||||
blkfree(blk);
|
||||
return(gres == gpol);
|
||||
}
|
||||
|
||||
static int
|
||||
pmatch(Char *string, Char *pattern)
|
||||
{
|
||||
int match, negate_range;
|
||||
Char patternc, rangec, stringc;
|
||||
|
||||
for (;; ++string) {
|
||||
stringc = *string & TRIM;
|
||||
patternc = *pattern++;
|
||||
switch (patternc) {
|
||||
case 0:
|
||||
return (stringc == 0);
|
||||
case '?':
|
||||
if (stringc == 0)
|
||||
return (0);
|
||||
break;
|
||||
case '*':
|
||||
if (!*pattern)
|
||||
return (1);
|
||||
while (*string)
|
||||
if (Gmatch(string++, pattern))
|
||||
return (1);
|
||||
return (0);
|
||||
case '[':
|
||||
match = 0;
|
||||
if ((negate_range = (*pattern == '^')) != 0)
|
||||
pattern++;
|
||||
while ((rangec = *pattern++) != '\0') {
|
||||
if (rangec == ']')
|
||||
break;
|
||||
if (match)
|
||||
continue;
|
||||
if (rangec == '-' && *(pattern-2) != '[' && *pattern != ']') {
|
||||
match = (stringc <= (*pattern & TRIM) &&
|
||||
(*(pattern-2) & TRIM) <= stringc);
|
||||
pattern++;
|
||||
}
|
||||
else
|
||||
match = (stringc == (rangec & TRIM));
|
||||
}
|
||||
if (rangec == 0)
|
||||
stderror(ERR_NAME | ERR_MISSING, ']');
|
||||
if (match == negate_range)
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
if ((patternc & TRIM) != stringc)
|
||||
return (0);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Gcat(Char *s1, Char *s2)
|
||||
{
|
||||
Char *p, *q;
|
||||
ptrdiff_t n;
|
||||
|
||||
for (p = s1; *p++;)
|
||||
continue;
|
||||
for (q = s2; *q++;)
|
||||
continue;
|
||||
n = (p - s1) + (q - s2) - 1;
|
||||
if (++gargc >= gargsiz) {
|
||||
gargsiz += GLOBSPACE;
|
||||
gargv = (Char **)xrealloc((ptr_t)gargv,
|
||||
(size_t)gargsiz * sizeof(Char *));
|
||||
}
|
||||
gargv[gargc] = 0;
|
||||
p = gargv[gargc - 1] = xmalloc((size_t)n * sizeof(Char));
|
||||
for (q = s1; (*p++ = *q++) != '\0';)
|
||||
continue;
|
||||
for (p--, q = s2; (*p++ = *q++) != '\0';)
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef FILEC
|
||||
int
|
||||
sortscmp(const ptr_t a, const ptr_t b)
|
||||
{
|
||||
#if defined(NLS) && !defined(NOSTRCOLL)
|
||||
char buf[2048];
|
||||
#endif
|
||||
|
||||
if (!a) /* check for NULL */
|
||||
return (b ? 1 : 0);
|
||||
if (!b)
|
||||
return (-1);
|
||||
|
||||
if (!*(Char **)a) /* check for NULL */
|
||||
return (*(Char **)b ? 1 : 0);
|
||||
if (!*(Char **)b)
|
||||
return (-1);
|
||||
|
||||
#if defined(NLS) && !defined(NOSTRCOLL)
|
||||
(void)strcpy(buf, short2str(*(Char **)a));
|
||||
return ((int)strcoll(buf, short2str(*(Char **)b)));
|
||||
#else
|
||||
return ((int)Strcmp(*(Char **)a, *(Char **)b));
|
||||
#endif
|
||||
}
|
||||
#endif /* FILEC */
|
||||
207
bin/csh/hist.c
Normal file
207
bin/csh/hist.c
Normal file
@@ -0,0 +1,207 @@
|
||||
/* $NetBSD: hist.c,v 1.20 2013/07/16 17:47:43 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: hist.c,v 1.20 2013/07/16 17:47:43 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
static void hfree(struct Hist *);
|
||||
static void dohist1(struct Hist *, int *, int, int);
|
||||
static void phist(struct Hist *, int);
|
||||
|
||||
void
|
||||
savehist(struct wordent *sp)
|
||||
{
|
||||
struct Hist *hp, *np;
|
||||
Char *cp;
|
||||
int histlen;
|
||||
|
||||
histlen = 0;
|
||||
|
||||
/* throw away null lines */
|
||||
if (sp->next->word[0] == '\n')
|
||||
return;
|
||||
cp = value(STRhistory);
|
||||
if (*cp) {
|
||||
Char *p = cp;
|
||||
|
||||
while (*p) {
|
||||
if (!Isdigit(*p)) {
|
||||
histlen = 0;
|
||||
break;
|
||||
}
|
||||
histlen = histlen * 10 + *p++ - '0';
|
||||
}
|
||||
}
|
||||
for (hp = &Histlist; (np = hp->Hnext) != NULL;)
|
||||
if (eventno - np->Href >= histlen || histlen == 0)
|
||||
hp->Hnext = np->Hnext, hfree(np);
|
||||
else
|
||||
hp = np;
|
||||
(void) enthist(++eventno, sp, 1);
|
||||
}
|
||||
|
||||
#ifdef EDIT
|
||||
void
|
||||
loadhist(struct Hist *hp) {
|
||||
char *h = NULL;
|
||||
|
||||
if (hi == NULL || hp == NULL)
|
||||
return;
|
||||
loadhist(hp->Hnext);
|
||||
if (sprlex(&h, &hp->Hlex) != -1) {
|
||||
HistEvent ev;
|
||||
history(hi, &ev, H_ENTER, h);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
struct Hist *
|
||||
enthist(int event, struct wordent *lp, int docopy)
|
||||
{
|
||||
struct Hist *np;
|
||||
|
||||
#ifdef EDIT
|
||||
if (hi) {
|
||||
char *h = NULL;
|
||||
if (sprlex(&h, lp) != -1) {
|
||||
HistEvent ev;
|
||||
history(hi, &ev, H_ENTER, h);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
np = xmalloc(sizeof(*np));
|
||||
np->Hnum = np->Href = event;
|
||||
if (docopy) {
|
||||
copylex(&np->Hlex, lp);
|
||||
}
|
||||
else {
|
||||
np->Hlex.next = lp->next;
|
||||
lp->next->prev = &np->Hlex;
|
||||
np->Hlex.prev = lp->prev;
|
||||
lp->prev->next = &np->Hlex;
|
||||
}
|
||||
np->Hnext = Histlist.Hnext;
|
||||
Histlist.Hnext = np;
|
||||
return (np);
|
||||
}
|
||||
|
||||
static void
|
||||
hfree(struct Hist *hp)
|
||||
{
|
||||
freelex(&hp->Hlex);
|
||||
xfree((ptr_t) hp);
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dohist(Char **v, struct command *t)
|
||||
{
|
||||
sigset_t nsigset;
|
||||
int hflg, n, rflg;
|
||||
|
||||
hflg = 0;
|
||||
rflg = 0;
|
||||
|
||||
if (getn(value(STRhistory)) == 0)
|
||||
return;
|
||||
if (setintr) {
|
||||
sigemptyset(&nsigset);
|
||||
(void)sigaddset(&nsigset, SIGINT);
|
||||
(void)sigprocmask(SIG_UNBLOCK, &nsigset, NULL);
|
||||
}
|
||||
while (*++v && **v == '-') {
|
||||
Char *vp = *v;
|
||||
|
||||
while (*++vp)
|
||||
switch (*vp) {
|
||||
case 'h':
|
||||
hflg++;
|
||||
break;
|
||||
case 'r':
|
||||
rflg++;
|
||||
break;
|
||||
case '-': /* ignore multiple '-'s */
|
||||
break;
|
||||
default:
|
||||
stderror(ERR_HISTUS);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
if (*v)
|
||||
n = getn(*v);
|
||||
else {
|
||||
n = getn(value(STRhistory));
|
||||
}
|
||||
dohist1(Histlist.Hnext, &n, rflg, hflg);
|
||||
}
|
||||
|
||||
static void
|
||||
dohist1(struct Hist *hp, int *np, int rflg, int hflg)
|
||||
{
|
||||
int print;
|
||||
|
||||
print = (*np) > 0;
|
||||
|
||||
for (; hp != 0; hp = hp->Hnext) {
|
||||
(*np)--;
|
||||
hp->Href++;
|
||||
if (rflg == 0) {
|
||||
dohist1(hp->Hnext, np, rflg, hflg);
|
||||
if (print)
|
||||
phist(hp, hflg);
|
||||
return;
|
||||
}
|
||||
if (*np >= 0)
|
||||
phist(hp, hflg);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
phist(struct Hist *hp, int hflg)
|
||||
{
|
||||
if (hflg == 0)
|
||||
(void)fprintf(cshout, "%6d\t", hp->Hnum);
|
||||
prlex(cshout, &hp->Hlex);
|
||||
}
|
||||
131
bin/csh/init.c
Normal file
131
bin/csh/init.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/* $NetBSD: init.c,v 1.11 2013/01/22 19:28:00 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)init.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: init.c,v 1.11 2013/01/22 19:28:00 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
#define INF 1000
|
||||
|
||||
struct biltins bfunc[] =
|
||||
{
|
||||
{ "@", dolet, 0, INF },
|
||||
{ "alias", doalias, 0, INF },
|
||||
{ "bg", dobg, 0, INF },
|
||||
{ "break", dobreak, 0, 0 },
|
||||
{ "breaksw", doswbrk, 0, 0 },
|
||||
{ "case", dozip, 0, 1 },
|
||||
{ "cd", dochngd, 0, INF },
|
||||
{ "chdir", dochngd, 0, INF },
|
||||
{ "continue", docontin, 0, 0 },
|
||||
{ "default", dozip, 0, 0 },
|
||||
{ "dirs", dodirs, 0, INF },
|
||||
{ "echo", doecho, 0, INF },
|
||||
{ "else", doelse, 0, INF },
|
||||
{ "end", doend, 0, 0 },
|
||||
{ "endif", dozip, 0, 0 },
|
||||
{ "endsw", dozip, 0, 0 },
|
||||
{ "eval", doeval, 0, INF },
|
||||
{ "exec", execash, 1, INF },
|
||||
{ "exit", doexit, 0, INF },
|
||||
{ "fg", dofg, 0, INF },
|
||||
{ "foreach", doforeach, 3, INF },
|
||||
{ "glob", doglob, 0, INF },
|
||||
{ "goto", dogoto, 1, 1 },
|
||||
{ "hashstat", hashstat, 0, 0 },
|
||||
{ "history", dohist, 0, 2 },
|
||||
{ "if", doif, 1, INF },
|
||||
{ "jobs", dojobs, 0, 1 },
|
||||
{ "kill", dokill, 1, INF },
|
||||
{ "limit", dolimit, 0, 3 },
|
||||
{ "linedit", doecho, 0, INF },
|
||||
{ "login", dologin, 0, 1 },
|
||||
{ "logout", dologout, 0, 0 },
|
||||
{ "nice", donice, 0, INF },
|
||||
{ "nohup", donohup, 0, INF },
|
||||
{ "notify", donotify, 0, INF },
|
||||
{ "onintr", doonintr, 0, 2 },
|
||||
{ "popd", dopopd, 0, INF },
|
||||
{ "printf", doprintf, 1, INF },
|
||||
{ "pushd", dopushd, 0, INF },
|
||||
{ "rehash", dohash, 0, 0 },
|
||||
{ "repeat", dorepeat, 2, INF },
|
||||
{ "set", doset, 0, INF },
|
||||
{ "setenv", dosetenv, 0, 2 },
|
||||
{ "shift", shift, 0, 1 },
|
||||
{ "source", dosource, 1, 2 },
|
||||
{ "stop", dostop, 1, INF },
|
||||
{ "suspend", dosuspend, 0, 0 },
|
||||
{ "switch", doswitch, 1, INF },
|
||||
{ "time", dotime, 0, INF },
|
||||
{ "umask", doumask, 0, 1 },
|
||||
{ "unalias", unalias, 1, INF },
|
||||
{ "unhash", dounhash, 0, 0 },
|
||||
{ "unlimit", dounlimit, 0, INF },
|
||||
{ "unset", unset, 1, INF },
|
||||
{ "unsetenv", dounsetenv, 1, INF },
|
||||
{ "wait", dowait, 0, 0 },
|
||||
{ "which", dowhich, 1, INF },
|
||||
{ "while", dowhile, 1, INF }
|
||||
};
|
||||
int nbfunc = sizeof(bfunc) / sizeof(*bfunc);
|
||||
|
||||
struct srch srchn[] =
|
||||
{
|
||||
{ "@", T_LET },
|
||||
{ "break", T_BREAK },
|
||||
{ "breaksw", T_BRKSW },
|
||||
{ "case", T_CASE },
|
||||
{ "default", T_DEFAULT },
|
||||
{ "else", T_ELSE },
|
||||
{ "end", T_END },
|
||||
{ "endif", T_ENDIF },
|
||||
{ "endsw", T_ENDSW },
|
||||
{ "exit", T_EXIT },
|
||||
{ "foreach", T_FOREACH },
|
||||
{ "goto", T_GOTO },
|
||||
{ "if", T_IF },
|
||||
{ "label", T_LABEL },
|
||||
{ "set", T_SET },
|
||||
{ "switch", T_SWITCH },
|
||||
{ "while", T_WHILE }
|
||||
};
|
||||
int nsrchn = sizeof(srchn) / sizeof(*srchn);
|
||||
1631
bin/csh/lex.c
Normal file
1631
bin/csh/lex.c
Normal file
File diff suppressed because it is too large
Load Diff
407
bin/csh/misc.c
Normal file
407
bin/csh/misc.c
Normal file
@@ -0,0 +1,407 @@
|
||||
/* $NetBSD: misc.c,v 1.20 2013/07/16 17:47:43 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: misc.c,v 1.20 2013/07/16 17:47:43 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
static int renum(int, int);
|
||||
|
||||
int
|
||||
any(const char *s, int c)
|
||||
{
|
||||
if (!s)
|
||||
return (0); /* Check for nil pointer */
|
||||
while (*s)
|
||||
if (*s++ == c)
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
char *
|
||||
strsave(const char *s)
|
||||
{
|
||||
const char *n;
|
||||
char *p, *r;
|
||||
|
||||
if (s == NULL)
|
||||
s = "";
|
||||
for (n = s; *n++;)
|
||||
continue;
|
||||
r = p = xmalloc((size_t)(n - s) * sizeof(*p));
|
||||
while ((*p++ = *s++) != '\0')
|
||||
continue;
|
||||
return (r);
|
||||
}
|
||||
|
||||
Char **
|
||||
blkend(Char **up)
|
||||
{
|
||||
while (*up)
|
||||
up++;
|
||||
return (up);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
blkpr(FILE *fp, Char **av)
|
||||
{
|
||||
for (; *av; av++) {
|
||||
(void)fprintf(fp, "%s", vis_str(*av));
|
||||
if (av[1])
|
||||
(void)fprintf(fp, " ");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
blklen(Char **av)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (*av++)
|
||||
i++;
|
||||
return (i);
|
||||
}
|
||||
|
||||
Char **
|
||||
blkcpy(Char **oav, Char **bv)
|
||||
{
|
||||
Char **av;
|
||||
|
||||
av = oav;
|
||||
while ((*av++ = *bv++) != NULL)
|
||||
continue;
|
||||
return (oav);
|
||||
}
|
||||
|
||||
Char **
|
||||
blkcat(Char **up, Char **vp)
|
||||
{
|
||||
(void)blkcpy(blkend(up), vp);
|
||||
return (up);
|
||||
}
|
||||
|
||||
void
|
||||
blkfree(Char **av0)
|
||||
{
|
||||
Char **av;
|
||||
|
||||
av = av0;
|
||||
if (!av0)
|
||||
return;
|
||||
for (; *av; av++)
|
||||
xfree((ptr_t) * av);
|
||||
xfree((ptr_t) av0);
|
||||
}
|
||||
|
||||
Char **
|
||||
saveblk(Char **v)
|
||||
{
|
||||
Char **newv, **onewv;
|
||||
|
||||
if (v == NULL)
|
||||
return NULL;
|
||||
|
||||
newv = xcalloc((size_t)(blklen(v) + 1), sizeof(*newv));
|
||||
onewv = newv;
|
||||
while (*v)
|
||||
*newv++ = Strsave(*v++);
|
||||
return (onewv);
|
||||
}
|
||||
|
||||
#ifdef NOTUSED
|
||||
char *
|
||||
strstr(char *s, char *t)
|
||||
{
|
||||
do {
|
||||
char *ss;
|
||||
char *tt;
|
||||
|
||||
ss = s;
|
||||
tt = t;
|
||||
|
||||
do
|
||||
if (*tt == '\0')
|
||||
return (s);
|
||||
while (*ss++ == *tt++);
|
||||
} while (*s++ != '\0');
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#endif /* NOTUSED */
|
||||
|
||||
#ifndef SHORT_STRINGS
|
||||
char *
|
||||
strspl(char *cp, char *dp)
|
||||
{
|
||||
char *ep, *p, *q;
|
||||
|
||||
if (!cp)
|
||||
cp = "";
|
||||
if (!dp)
|
||||
dp = "";
|
||||
for (p = cp; *p++;)
|
||||
continue;
|
||||
for (q = dp; *q++;)
|
||||
continue;
|
||||
ep = xmalloc((size_t)(((p - cp) + (q - dp) - 1) * sizeof(*ep)));
|
||||
for (p = ep, q = cp; *p++ = *q++;)
|
||||
continue;
|
||||
for (p--, q = dp; *p++ = *q++;)
|
||||
continue;
|
||||
return (ep);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Char **
|
||||
blkspl(Char **up, Char **vp)
|
||||
{
|
||||
Char **wp;
|
||||
|
||||
wp = xcalloc((size_t)(blklen(up) + blklen(vp) + 1), sizeof(*wp));
|
||||
(void)blkcpy(wp, up);
|
||||
return (blkcat(wp, vp));
|
||||
}
|
||||
|
||||
Char
|
||||
lastchr(Char *cp)
|
||||
{
|
||||
if (!cp)
|
||||
return (0);
|
||||
if (!*cp)
|
||||
return (0);
|
||||
while (cp[1])
|
||||
cp++;
|
||||
return (*cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine is called after an error to close up
|
||||
* any units which may have been left open accidentally.
|
||||
*/
|
||||
void
|
||||
closem(void)
|
||||
{
|
||||
int f;
|
||||
int nofile;
|
||||
|
||||
#ifdef F_CLOSEM
|
||||
nofile = FOLDSTD + 1;
|
||||
if (fcntl(nofile, F_CLOSEM, 0) == -1)
|
||||
#endif
|
||||
nofile = NOFILE;
|
||||
|
||||
for (f = 0; f < nofile; f++)
|
||||
if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD &&
|
||||
f != FSHTTY)
|
||||
(void) close(f);
|
||||
}
|
||||
|
||||
void
|
||||
donefds(void)
|
||||
{
|
||||
(void)close(0);
|
||||
(void)close(1);
|
||||
(void)close(2);
|
||||
|
||||
didfds = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move descriptor i to j.
|
||||
* If j is -1 then we just want to get i to a safe place,
|
||||
* i.e. to a unit > 2. This also happens in dcopy.
|
||||
*/
|
||||
int
|
||||
dmove(int i, int j)
|
||||
{
|
||||
if (i == j || i < 0)
|
||||
return (i);
|
||||
if (j >= 0) {
|
||||
(void)dup2(i, j);
|
||||
if (j != i)
|
||||
(void)close(i);
|
||||
return (j);
|
||||
}
|
||||
j = dcopy(i, j);
|
||||
if (j != i)
|
||||
(void)close(i);
|
||||
return (j);
|
||||
}
|
||||
|
||||
int
|
||||
dcopy(int i, int j)
|
||||
{
|
||||
if (i == j || i < 0 || (j < 0 && i > 2))
|
||||
return (i);
|
||||
if (j >= 0) {
|
||||
(void)dup2(i, j);
|
||||
return (j);
|
||||
}
|
||||
return (renum(i, j));
|
||||
}
|
||||
|
||||
static int
|
||||
renum(int i, int j)
|
||||
{
|
||||
int k;
|
||||
|
||||
k = dup(i);
|
||||
if (k < 0)
|
||||
return (-1);
|
||||
if (j == -1 && k > 2)
|
||||
return (k);
|
||||
if (k != j) {
|
||||
j = renum(k, j);
|
||||
(void)close(k);
|
||||
return (j);
|
||||
}
|
||||
return (k);
|
||||
}
|
||||
|
||||
/*
|
||||
* Left shift a command argument list, discarding
|
||||
* the first c arguments. Used in "shift" commands
|
||||
* as well as by commands like "repeat".
|
||||
*/
|
||||
void
|
||||
lshift(Char **v, size_t c)
|
||||
{
|
||||
Char **u;
|
||||
|
||||
for (u = v; *u && c-- > 0; u++)
|
||||
xfree((ptr_t) *u);
|
||||
(void)blkcpy(v, u);
|
||||
}
|
||||
|
||||
int
|
||||
number(Char *cp)
|
||||
{
|
||||
if (!cp)
|
||||
return(0);
|
||||
if (*cp == '-') {
|
||||
cp++;
|
||||
if (!Isdigit(*cp))
|
||||
return (0);
|
||||
cp++;
|
||||
}
|
||||
while (*cp && Isdigit(*cp))
|
||||
cp++;
|
||||
return (*cp == 0);
|
||||
}
|
||||
|
||||
Char **
|
||||
copyblk(Char **v)
|
||||
{
|
||||
Char **nv;
|
||||
|
||||
nv = xcalloc((size_t)(blklen(v) + 1), sizeof(*nv));
|
||||
|
||||
return (blkcpy(nv, v));
|
||||
}
|
||||
|
||||
#ifndef SHORT_STRINGS
|
||||
char *
|
||||
strend(char *cp)
|
||||
{
|
||||
if (!cp)
|
||||
return (cp);
|
||||
while (*cp)
|
||||
cp++;
|
||||
return (cp);
|
||||
}
|
||||
|
||||
#endif /* SHORT_STRINGS */
|
||||
|
||||
Char *
|
||||
strip(Char *cp)
|
||||
{
|
||||
Char *dp;
|
||||
|
||||
dp = cp;
|
||||
if (!cp)
|
||||
return (cp);
|
||||
while ((*dp++ &= TRIM) != '\0')
|
||||
continue;
|
||||
return (cp);
|
||||
}
|
||||
|
||||
Char *
|
||||
quote(Char *cp)
|
||||
{
|
||||
Char *dp;
|
||||
|
||||
dp = cp;
|
||||
if (!cp)
|
||||
return (cp);
|
||||
while (*dp != '\0')
|
||||
*dp++ |= QUOTE;
|
||||
return (cp);
|
||||
}
|
||||
|
||||
void
|
||||
udvar(Char *name)
|
||||
{
|
||||
setname(vis_str(name));
|
||||
stderror(ERR_NAME | ERR_UNDVAR);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
int
|
||||
prefix(Char *sub, Char *str)
|
||||
{
|
||||
for (;;) {
|
||||
if (*sub == 0)
|
||||
return (1);
|
||||
if (*str == 0)
|
||||
return (0);
|
||||
if (*sub++ != *str++)
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
640
bin/csh/parse.c
Normal file
640
bin/csh/parse.c
Normal file
@@ -0,0 +1,640 @@
|
||||
/* $NetBSD: parse.c,v 1.17 2007/07/16 18:26:10 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: parse.c,v 1.17 2007/07/16 18:26:10 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
static void asyntax(struct wordent *, struct wordent *);
|
||||
static void asyn0(struct wordent *, struct wordent *);
|
||||
static void asyn3(struct wordent *, struct wordent *);
|
||||
static struct wordent *freenod(struct wordent *, struct wordent *);
|
||||
static struct command *syn0(struct wordent *, struct wordent *, int);
|
||||
static struct command *syn1(struct wordent *, struct wordent *, int);
|
||||
static struct command *syn1a(struct wordent *, struct wordent *, int);
|
||||
static struct command *syn1b(struct wordent *, struct wordent *, int);
|
||||
static struct command *syn2(struct wordent *, struct wordent *, int);
|
||||
static struct command *syn3(struct wordent *, struct wordent *, int);
|
||||
|
||||
#define ALEFT 21 /* max of 20 alias expansions */
|
||||
#define HLEFT 11 /* max of 10 history expansions */
|
||||
/*
|
||||
* Perform aliasing on the word list lex
|
||||
* Do a (very rudimentary) parse to separate into commands.
|
||||
* If word 0 of a command has an alias, do it.
|
||||
* Repeat a maximum of 20 times.
|
||||
*/
|
||||
static int aleft;
|
||||
extern int hleft;
|
||||
|
||||
void
|
||||
alias(struct wordent *lexp)
|
||||
{
|
||||
jmp_buf osetexit;
|
||||
|
||||
aleft = ALEFT;
|
||||
hleft = HLEFT;
|
||||
getexit(osetexit);
|
||||
(void)setexit();
|
||||
if (haderr) {
|
||||
resexit(osetexit);
|
||||
reset();
|
||||
}
|
||||
if (--aleft == 0)
|
||||
stderror(ERR_ALIASLOOP);
|
||||
asyntax(lexp->next, lexp);
|
||||
resexit(osetexit);
|
||||
}
|
||||
|
||||
static void
|
||||
asyntax(struct wordent *p1, struct wordent *p2)
|
||||
{
|
||||
while (p1 != p2)
|
||||
if (any(";&\n", p1->word[0]))
|
||||
p1 = p1->next;
|
||||
else {
|
||||
asyn0(p1, p2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
asyn0(struct wordent *p1, struct wordent *p2)
|
||||
{
|
||||
struct wordent *p;
|
||||
int l;
|
||||
|
||||
l = 0;
|
||||
for (p = p1; p != p2; p = p->next)
|
||||
switch (p->word[0]) {
|
||||
case '(':
|
||||
l++;
|
||||
continue;
|
||||
case ')':
|
||||
l--;
|
||||
if (l < 0)
|
||||
stderror(ERR_TOOMANYRP);
|
||||
continue;
|
||||
case '>':
|
||||
if (p->next != p2 && eq(p->next->word, STRand))
|
||||
p = p->next;
|
||||
continue;
|
||||
case '&':
|
||||
case '|':
|
||||
case ';':
|
||||
case '\n':
|
||||
if (l != 0)
|
||||
continue;
|
||||
asyn3(p1, p);
|
||||
asyntax(p->next, p2);
|
||||
return;
|
||||
}
|
||||
if (l == 0)
|
||||
asyn3(p1, p2);
|
||||
}
|
||||
|
||||
static void
|
||||
asyn3(struct wordent *p1, struct wordent *p2)
|
||||
{
|
||||
struct varent *ap;
|
||||
struct wordent alout;
|
||||
int redid;
|
||||
|
||||
if (p1 == p2)
|
||||
return;
|
||||
if (p1->word[0] == '(') {
|
||||
for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev)
|
||||
if (p2 == p1)
|
||||
return;
|
||||
if (p2 == p1->next)
|
||||
return;
|
||||
asyn0(p1->next, p2);
|
||||
return;
|
||||
}
|
||||
ap = adrof1(p1->word, &aliases);
|
||||
if (ap == 0)
|
||||
return;
|
||||
alhistp = p1->prev;
|
||||
alhistt = p2;
|
||||
alvec = ap->vec;
|
||||
redid = lex(&alout);
|
||||
alhistp = alhistt = 0;
|
||||
alvec = 0;
|
||||
if (seterr) {
|
||||
freelex(&alout);
|
||||
stderror(ERR_OLD);
|
||||
}
|
||||
if (p1->word[0] && eq(p1->word, alout.next->word)) {
|
||||
Char *cp;
|
||||
|
||||
cp = alout.next->word;
|
||||
alout.next->word = Strspl(STRQNULL, cp);
|
||||
xfree((ptr_t) cp);
|
||||
}
|
||||
p1 = freenod(p1, redid ? p2 : p1->next);
|
||||
if (alout.next != &alout) {
|
||||
p1->next->prev = alout.prev->prev;
|
||||
alout.prev->prev->next = p1->next;
|
||||
alout.next->prev = p1;
|
||||
p1->next = alout.next;
|
||||
xfree((ptr_t)alout.prev->word);
|
||||
xfree((ptr_t)(alout.prev));
|
||||
}
|
||||
reset(); /* throw! */
|
||||
}
|
||||
|
||||
static struct wordent *
|
||||
freenod(struct wordent *p1, struct wordent *p2)
|
||||
{
|
||||
struct wordent *retp;
|
||||
|
||||
retp = p1->prev;
|
||||
while (p1 != p2) {
|
||||
xfree((ptr_t)p1->word);
|
||||
p1 = p1->next;
|
||||
xfree((ptr_t) (p1->prev));
|
||||
}
|
||||
retp->next = p2;
|
||||
p2->prev = retp;
|
||||
return (retp);
|
||||
}
|
||||
|
||||
#define PHERE 1
|
||||
#define PIN 2
|
||||
#define POUT 4
|
||||
#define PERR 8
|
||||
|
||||
/*
|
||||
* syntax
|
||||
* empty
|
||||
* syn0
|
||||
*/
|
||||
struct command *
|
||||
syntax(struct wordent *p1, struct wordent *p2, int flags)
|
||||
{
|
||||
while (p1 != p2)
|
||||
if (any(";&\n", p1->word[0]))
|
||||
p1 = p1->next;
|
||||
else
|
||||
return (syn0(p1, p2, flags));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* syn0
|
||||
* syn1
|
||||
* syn1 & syntax
|
||||
*/
|
||||
static struct command *
|
||||
syn0(struct wordent *p1, struct wordent *p2, int flags)
|
||||
{
|
||||
struct wordent *p;
|
||||
struct command *t, *t1;
|
||||
int l;
|
||||
|
||||
l = 0;
|
||||
for (p = p1; p != p2; p = p->next)
|
||||
switch (p->word[0]) {
|
||||
case '(':
|
||||
l++;
|
||||
continue;
|
||||
case ')':
|
||||
l--;
|
||||
if (l < 0)
|
||||
seterror(ERR_TOOMANYRP);
|
||||
continue;
|
||||
case '|':
|
||||
if (p->word[1] == '|')
|
||||
continue;
|
||||
/* FALLTHROUGH */
|
||||
case '>':
|
||||
if (p->next != p2 && eq(p->next->word, STRand))
|
||||
p = p->next;
|
||||
continue;
|
||||
case '&':
|
||||
if (l != 0)
|
||||
break;
|
||||
if (p->word[1] == '&')
|
||||
continue;
|
||||
t1 = syn1(p1, p, flags);
|
||||
if (t1->t_dtyp == NODE_LIST ||
|
||||
t1->t_dtyp == NODE_AND ||
|
||||
t1->t_dtyp == NODE_OR) {
|
||||
t = (struct command *)xcalloc(1, sizeof(*t));
|
||||
t->t_dtyp = NODE_PAREN;
|
||||
t->t_dflg = F_AMPERSAND | F_NOINTERRUPT;
|
||||
t->t_dspr = t1;
|
||||
t1 = t;
|
||||
}
|
||||
else
|
||||
t1->t_dflg |= F_AMPERSAND | F_NOINTERRUPT;
|
||||
t = (struct command *)xcalloc(1, sizeof(*t));
|
||||
t->t_dtyp = NODE_LIST;
|
||||
t->t_dflg = 0;
|
||||
t->t_dcar = t1;
|
||||
t->t_dcdr = syntax(p, p2, flags);
|
||||
return (t);
|
||||
}
|
||||
if (l == 0)
|
||||
return (syn1(p1, p2, flags));
|
||||
seterror(ERR_TOOMANYLP);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* syn1
|
||||
* syn1a
|
||||
* syn1a ; syntax
|
||||
*/
|
||||
static struct command *
|
||||
syn1(struct wordent *p1, struct wordent *p2, int flags)
|
||||
{
|
||||
struct wordent *p;
|
||||
struct command *t;
|
||||
int l;
|
||||
|
||||
l = 0;
|
||||
for (p = p1; p != p2; p = p->next)
|
||||
switch (p->word[0]) {
|
||||
case '(':
|
||||
l++;
|
||||
continue;
|
||||
case ')':
|
||||
l--;
|
||||
continue;
|
||||
case ';':
|
||||
case '\n':
|
||||
if (l != 0)
|
||||
break;
|
||||
t = (struct command *) xcalloc(1, sizeof(*t));
|
||||
t->t_dtyp = NODE_LIST;
|
||||
t->t_dcar = syn1a(p1, p, flags);
|
||||
t->t_dcdr = syntax(p->next, p2, flags);
|
||||
if (t->t_dcdr == 0)
|
||||
t->t_dcdr = t->t_dcar, t->t_dcar = 0;
|
||||
return (t);
|
||||
}
|
||||
return (syn1a(p1, p2, flags));
|
||||
}
|
||||
|
||||
/*
|
||||
* syn1a
|
||||
* syn1b
|
||||
* syn1b || syn1a
|
||||
*/
|
||||
static struct command *
|
||||
syn1a(struct wordent *p1, struct wordent *p2, int flags)
|
||||
{
|
||||
struct wordent *p;
|
||||
struct command *t;
|
||||
int l;
|
||||
|
||||
l = 0;
|
||||
for (p = p1; p != p2; p = p->next)
|
||||
switch (p->word[0]) {
|
||||
case '(':
|
||||
l++;
|
||||
continue;
|
||||
case ')':
|
||||
l--;
|
||||
continue;
|
||||
case '|':
|
||||
if (p->word[1] != '|')
|
||||
continue;
|
||||
if (l == 0) {
|
||||
t = (struct command *)xcalloc(1, sizeof(*t));
|
||||
t->t_dtyp = NODE_OR;
|
||||
t->t_dcar = syn1b(p1, p, flags);
|
||||
t->t_dcdr = syn1a(p->next, p2, flags);
|
||||
t->t_dflg = 0;
|
||||
return (t);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return (syn1b(p1, p2, flags));
|
||||
}
|
||||
|
||||
/*
|
||||
* syn1b
|
||||
* syn2
|
||||
* syn2 && syn1b
|
||||
*/
|
||||
static struct command *
|
||||
syn1b(struct wordent *p1, struct wordent *p2, int flags)
|
||||
{
|
||||
struct wordent *p;
|
||||
struct command *t;
|
||||
int l;
|
||||
|
||||
l = 0;
|
||||
for (p = p1; p != p2; p = p->next)
|
||||
switch (p->word[0]) {
|
||||
case '(':
|
||||
l++;
|
||||
continue;
|
||||
case ')':
|
||||
l--;
|
||||
continue;
|
||||
case '&':
|
||||
if (p->word[1] == '&' && l == 0) {
|
||||
t = (struct command *)xcalloc(1, sizeof(*t));
|
||||
t->t_dtyp = NODE_AND;
|
||||
t->t_dcar = syn2(p1, p, flags);
|
||||
t->t_dcdr = syn1b(p->next, p2, flags);
|
||||
t->t_dflg = 0;
|
||||
return (t);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return (syn2(p1, p2, flags));
|
||||
}
|
||||
|
||||
/*
|
||||
* syn2
|
||||
* syn3
|
||||
* syn3 | syn2
|
||||
* syn3 |& syn2
|
||||
*/
|
||||
static struct command *
|
||||
syn2(struct wordent *p1, struct wordent *p2, int flags)
|
||||
{
|
||||
struct wordent *p, *pn;
|
||||
struct command *t;
|
||||
int f, l;
|
||||
|
||||
l = 0;
|
||||
for (p = p1; p != p2; p = p->next)
|
||||
switch (p->word[0]) {
|
||||
case '(':
|
||||
l++;
|
||||
continue;
|
||||
case ')':
|
||||
l--;
|
||||
continue;
|
||||
case '|':
|
||||
if (l != 0)
|
||||
continue;
|
||||
t = (struct command *)xcalloc(1, sizeof(*t));
|
||||
f = flags | POUT;
|
||||
pn = p->next;
|
||||
if (pn != p2 && pn->word[0] == '&') {
|
||||
f |= PERR;
|
||||
t->t_dflg |= F_STDERR;
|
||||
}
|
||||
t->t_dtyp = NODE_PIPE;
|
||||
t->t_dcar = syn3(p1, p, f);
|
||||
if (pn != p2 && pn->word[0] == '&')
|
||||
p = pn;
|
||||
t->t_dcdr = syn2(p->next, p2, flags | PIN);
|
||||
return (t);
|
||||
}
|
||||
return (syn3(p1, p2, flags));
|
||||
}
|
||||
|
||||
static char RELPAR[] = {'<', '>', '(', ')', '\0'};
|
||||
|
||||
/*
|
||||
* syn3
|
||||
* ( syn0 ) [ < in ] [ > out ]
|
||||
* word word* [ < in ] [ > out ]
|
||||
* KEYWORD ( word* ) word* [ < in ] [ > out ]
|
||||
*
|
||||
* KEYWORD = (@ exit foreach if set switch test while)
|
||||
*/
|
||||
static struct command *
|
||||
syn3(struct wordent *p1, struct wordent *p2, int flags)
|
||||
{
|
||||
struct wordent *lp, *p, *rp;
|
||||
struct command *t;
|
||||
Char **av;
|
||||
int c, l, n;
|
||||
int specp;
|
||||
|
||||
specp = 0;
|
||||
if (p1 != p2) {
|
||||
p = p1;
|
||||
again:
|
||||
switch (srchx(p->word)) {
|
||||
case T_ELSE:
|
||||
p = p->next;
|
||||
if (p != p2)
|
||||
goto again;
|
||||
break;
|
||||
case T_EXIT:
|
||||
case T_FOREACH:
|
||||
case T_IF:
|
||||
case T_LET:
|
||||
case T_SET:
|
||||
case T_SWITCH:
|
||||
case T_WHILE:
|
||||
specp = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
n = 0;
|
||||
l = 0;
|
||||
for (p = p1; p != p2; p = p->next)
|
||||
switch (p->word[0]) {
|
||||
case '(':
|
||||
if (specp)
|
||||
n++;
|
||||
l++;
|
||||
continue;
|
||||
case ')':
|
||||
if (specp)
|
||||
n++;
|
||||
l--;
|
||||
continue;
|
||||
case '>':
|
||||
case '<':
|
||||
if (l != 0) {
|
||||
if (specp)
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
if (p->next == p2)
|
||||
continue;
|
||||
if (any(RELPAR, p->next->word[0]))
|
||||
continue;
|
||||
n--;
|
||||
continue;
|
||||
default:
|
||||
if (!specp && l != 0)
|
||||
continue;
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
if (n < 0)
|
||||
n = 0;
|
||||
t = (struct command *)xcalloc(1, sizeof(*t));
|
||||
av = (Char **)xcalloc((size_t)(n + 1), sizeof(Char **));
|
||||
t->t_dcom = av;
|
||||
n = 0;
|
||||
if (p2->word[0] == ')')
|
||||
t->t_dflg = F_NOFORK;
|
||||
lp = 0;
|
||||
rp = 0;
|
||||
l = 0;
|
||||
for (p = p1; p != p2; p = p->next) {
|
||||
c = p->word[0];
|
||||
switch (c) {
|
||||
case '(':
|
||||
if (l == 0) {
|
||||
if (lp != 0 && !specp)
|
||||
seterror(ERR_BADPLP);
|
||||
lp = p->next;
|
||||
}
|
||||
l++;
|
||||
goto savep;
|
||||
case ')':
|
||||
l--;
|
||||
if (l == 0)
|
||||
rp = p;
|
||||
goto savep;
|
||||
case '>':
|
||||
if (l != 0)
|
||||
goto savep;
|
||||
if (p->word[1] == '>')
|
||||
t->t_dflg |= F_APPEND;
|
||||
if (p->next != p2 && eq(p->next->word, STRand)) {
|
||||
t->t_dflg |= F_STDERR, p = p->next;
|
||||
if (flags & (POUT | PERR)) {
|
||||
seterror(ERR_OUTRED);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (p->next != p2 && eq(p->next->word, STRbang))
|
||||
t->t_dflg |= F_OVERWRITE, p = p->next;
|
||||
if (p->next == p2) {
|
||||
seterror(ERR_MISRED);
|
||||
continue;
|
||||
}
|
||||
p = p->next;
|
||||
if (any(RELPAR, p->word[0])) {
|
||||
seterror(ERR_MISRED);
|
||||
continue;
|
||||
}
|
||||
if ((flags & POUT) && ((flags & PERR) == 0 || t->t_drit))
|
||||
seterror(ERR_OUTRED);
|
||||
else
|
||||
t->t_drit = Strsave(p->word);
|
||||
continue;
|
||||
case '<':
|
||||
if (l != 0)
|
||||
goto savep;
|
||||
if (p->word[1] == '<')
|
||||
t->t_dflg |= F_READ;
|
||||
if (p->next == p2) {
|
||||
seterror(ERR_MISRED);
|
||||
continue;
|
||||
}
|
||||
p = p->next;
|
||||
if (any(RELPAR, p->word[0])) {
|
||||
seterror(ERR_MISRED);
|
||||
continue;
|
||||
}
|
||||
if ((flags & PHERE) && (t->t_dflg & F_READ))
|
||||
seterror(ERR_REDPAR);
|
||||
else if ((flags & PIN) || t->t_dlef)
|
||||
seterror(ERR_INRED);
|
||||
else
|
||||
t->t_dlef = Strsave(p->word);
|
||||
continue;
|
||||
savep:
|
||||
if (!specp)
|
||||
continue;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
if (l != 0 && !specp)
|
||||
continue;
|
||||
if (seterr == 0)
|
||||
av[n] = Strsave(p->word);
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (lp != 0 && !specp) {
|
||||
if (n != 0)
|
||||
seterror(ERR_BADPLPS);
|
||||
t->t_dtyp = NODE_PAREN;
|
||||
t->t_dspr = syn0(lp, rp, PHERE);
|
||||
}
|
||||
else {
|
||||
if (n == 0)
|
||||
seterror(ERR_NULLCOM);
|
||||
t->t_dtyp = NODE_COMMAND;
|
||||
}
|
||||
return (t);
|
||||
}
|
||||
|
||||
void
|
||||
freesyn(struct command *t)
|
||||
{
|
||||
Char **v;
|
||||
|
||||
if (t == 0)
|
||||
return;
|
||||
switch (t->t_dtyp) {
|
||||
case NODE_COMMAND:
|
||||
for (v = t->t_dcom; *v; v++)
|
||||
xfree((ptr_t) * v);
|
||||
xfree((ptr_t)(t->t_dcom));
|
||||
xfree((ptr_t)t->t_dlef);
|
||||
xfree((ptr_t)t->t_drit);
|
||||
break;
|
||||
case NODE_PAREN:
|
||||
freesyn(t->t_dspr);
|
||||
xfree((ptr_t)t->t_dlef);
|
||||
xfree((ptr_t)t->t_drit);
|
||||
break;
|
||||
case NODE_AND:
|
||||
case NODE_OR:
|
||||
case NODE_PIPE:
|
||||
case NODE_LIST:
|
||||
freesyn(t->t_dcar), freesyn(t->t_dcdr);
|
||||
break;
|
||||
}
|
||||
xfree((ptr_t)t);
|
||||
}
|
||||
44
bin/csh/pathnames.h
Normal file
44
bin/csh/pathnames.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* $NetBSD: pathnames.h,v 1.8 2003/08/07 09:05:06 agc 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.
|
||||
*
|
||||
* @(#)pathnames.h 8.1 (Berkeley) 5/31/93
|
||||
*/
|
||||
|
||||
#ifndef _PATHNAMES_H_
|
||||
#define _PATHNAMES_H_
|
||||
|
||||
#define _PATH_BIN "/bin"
|
||||
#define _PATH_DOTCSHRC "/etc/csh.cshrc"
|
||||
#define _PATH_DOTLOGIN "/etc/csh.login"
|
||||
#define _PATH_DOTLOGOUT "/etc/csh.logout"
|
||||
#define _PATH_LOGIN "/usr/bin/login"
|
||||
#define _PATH_USRBIN "/usr/bin"
|
||||
|
||||
#endif /* !_PATHNAMES_H_ */
|
||||
1359
bin/csh/proc.c
Normal file
1359
bin/csh/proc.c
Normal file
File diff suppressed because it is too large
Load Diff
104
bin/csh/proc.h
Normal file
104
bin/csh/proc.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/* $NetBSD: proc.h,v 1.14 2013/07/16 17:47:43 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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.
|
||||
*
|
||||
* @(#)proc.h 8.1 (Berkeley) 5/31/93
|
||||
*/
|
||||
|
||||
#ifndef _PROC_H_
|
||||
#define _PROC_H_
|
||||
|
||||
/*
|
||||
* Structure for each process the shell knows about:
|
||||
* allocated and filled by pcreate.
|
||||
* flushed by pflush; freeing always happens at top level
|
||||
* so the interrupt level has less to worry about.
|
||||
* processes are related to "friends" when in a pipeline;
|
||||
* p_friends links makes a circular list of such jobs
|
||||
*/
|
||||
struct process {
|
||||
struct process *p_next; /* next in global "proclist" */
|
||||
struct process *p_friends; /* next in job list (or self) */
|
||||
struct directory *p_cwd; /* cwd of the job (only in head) */
|
||||
int p_flags; /* various job status flags */
|
||||
int p_reason; /* reason for entering this state */
|
||||
int p_index; /* shorthand job index */
|
||||
pid_t p_pid;
|
||||
pid_t p_jobid; /* pid of job leader */
|
||||
/* if a job is stopped/background p_jobid gives its pgrp */
|
||||
struct timespec p_btime; /* begin time */
|
||||
struct timespec p_etime; /* end time */
|
||||
struct rusage p_rusage;
|
||||
Char *p_command; /* first PMAXLEN chars of command */
|
||||
};
|
||||
|
||||
/* flag values for p_flags */
|
||||
#define PRUNNING (1<<0) /* running */
|
||||
#define PSTOPPED (1<<1) /* stopped */
|
||||
#define PNEXITED (1<<2) /* normally exited */
|
||||
#define PAEXITED (1<<3) /* abnormally exited */
|
||||
#define PSIGNALED (1<<4) /* terminated by a signal != SIGINT */
|
||||
#define PNOTIFY (1<<5) /* notify async when done */
|
||||
#define PTIME (1<<6) /* job times should be printed */
|
||||
#define PAWAITED (1<<7) /* top level is waiting for it */
|
||||
#define PFOREGND (1<<8) /* started in shells pgrp */
|
||||
#define PDUMPED (1<<9) /* process dumped core */
|
||||
#define PERR (1<<10) /* diagnostic output also piped out */
|
||||
#define PPOU (1<<11) /* piped output */
|
||||
#define PREPORTED (1<<12) /* status has been reported */
|
||||
#define PINTERRUPTED (1<<13) /* job stopped via interrupt signal */
|
||||
#define PPTIME (1<<14) /* time individual process */
|
||||
#define PNEEDNOTE (1<<15) /* notify as soon as practical */
|
||||
|
||||
#define PALLSTATES (PRUNNING|PSTOPPED|PNEXITED|PAEXITED|PSIGNALED|PINTERRUPTED)
|
||||
|
||||
#define PMAXLEN 80
|
||||
|
||||
/* defines for arguments to pprint */
|
||||
#define NUMBER 01
|
||||
#define NAME 02
|
||||
#define REASON 04
|
||||
#define AMPERSAND 010
|
||||
#define FANCY 020
|
||||
#define SHELLDIR 040 /* print shell's dir if not the same */
|
||||
#define JOBDIR 0100 /* print job's dir if not the same */
|
||||
#define AREASON 0200
|
||||
|
||||
struct process proclist; /* list head of all processes */
|
||||
int pnoprocesses; /* pchild found nothing to wait for */
|
||||
|
||||
struct process *pholdjob; /* one level stack of current jobs */
|
||||
|
||||
struct process *pcurrjob; /* current job */
|
||||
struct process *pcurrent; /* current job in table */
|
||||
struct process *pprevious; /* previous job in table */
|
||||
|
||||
int pmaxindex; /* current maximum job index */
|
||||
|
||||
#endif /* !_PROC_H_ */
|
||||
646
bin/csh/sem.c
Normal file
646
bin/csh/sem.c
Normal file
@@ -0,0 +1,646 @@
|
||||
/* $NetBSD: sem.c,v 1.29 2011/08/29 14:51:17 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)sem.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: sem.c,v 1.29 2011/08/29 14:51:17 joerg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
#include "proc.h"
|
||||
|
||||
__dead static void vffree(int);
|
||||
static Char *splicepipe(struct command *t, Char *);
|
||||
static void doio(struct command *t, int *, int *);
|
||||
static void chkclob(char *);
|
||||
|
||||
void
|
||||
execute(struct command *t, int wtty, int *pipein, int *pipeout)
|
||||
{
|
||||
static sigset_t csigset, ocsigset;
|
||||
static int nosigchld = 0, onosigchld = 0;
|
||||
volatile int wanttty = wtty;
|
||||
struct biltins * volatile bifunc;
|
||||
int pv[2], pid;
|
||||
sigset_t nsigset;
|
||||
int forked;
|
||||
|
||||
UNREGISTER(forked);
|
||||
UNREGISTER(bifunc);
|
||||
UNREGISTER(wanttty);
|
||||
|
||||
forked = 0;
|
||||
pid = 0;
|
||||
|
||||
if (t == 0)
|
||||
return;
|
||||
|
||||
if (t->t_dflg & F_AMPERSAND)
|
||||
wanttty = 0;
|
||||
switch (t->t_dtyp) {
|
||||
case NODE_COMMAND:
|
||||
if ((t->t_dcom[0][0] & (QUOTE | TRIM)) == QUOTE)
|
||||
(void)Strcpy(t->t_dcom[0], t->t_dcom[0] + 1);
|
||||
if ((t->t_dflg & F_REPEAT) == 0)
|
||||
Dfix(t); /* $ " ' \ */
|
||||
if (t->t_dcom[0] == 0)
|
||||
return;
|
||||
/* FALLTHROUGH */
|
||||
case NODE_PAREN:
|
||||
if (t->t_dflg & F_PIPEOUT)
|
||||
mypipe(pipeout);
|
||||
/*
|
||||
* Must do << early so parent will know where input pointer should be.
|
||||
* If noexec then this is all we do.
|
||||
*/
|
||||
if (t->t_dflg & F_READ) {
|
||||
(void)close(0);
|
||||
heredoc(t->t_dlef);
|
||||
if (noexec)
|
||||
(void)close(0);
|
||||
}
|
||||
|
||||
set(STRstatus, Strsave(STR0));
|
||||
|
||||
/*
|
||||
* This mess is the necessary kludge to handle the prefix builtins:
|
||||
* nice, nohup, time. These commands can also be used by themselves,
|
||||
* and this is not handled here. This will also work when loops are
|
||||
* parsed.
|
||||
*/
|
||||
while (t->t_dtyp == NODE_COMMAND)
|
||||
if (eq(t->t_dcom[0], STRnice)) {
|
||||
if (t->t_dcom[1]) {
|
||||
if (strchr("+-", t->t_dcom[1][0])) {
|
||||
if (t->t_dcom[2]) {
|
||||
setname("nice");
|
||||
t->t_nice =
|
||||
getn(t->t_dcom[1]);
|
||||
lshift(t->t_dcom, 2);
|
||||
t->t_dflg |= F_NICE;
|
||||
}
|
||||
else
|
||||
break;
|
||||
} else {
|
||||
t->t_nice = 4;
|
||||
lshift(t->t_dcom, 1);
|
||||
t->t_dflg |= F_NICE;
|
||||
}
|
||||
} else
|
||||
break;
|
||||
} else if (eq(t->t_dcom[0], STRnohup)) {
|
||||
if (t->t_dcom[1]) {
|
||||
t->t_dflg |= F_NOHUP;
|
||||
lshift(t->t_dcom, 1);
|
||||
}
|
||||
else
|
||||
break;
|
||||
} else if (eq(t->t_dcom[0], STRtime)) {
|
||||
if (t->t_dcom[1]) {
|
||||
t->t_dflg |= F_TIME;
|
||||
lshift(t->t_dcom, 1);
|
||||
}
|
||||
else
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
|
||||
/* is it a command */
|
||||
if (t->t_dtyp == NODE_COMMAND) {
|
||||
/*
|
||||
* Check if we have a builtin function and remember which one.
|
||||
*/
|
||||
bifunc = isbfunc(t);
|
||||
if (noexec && bifunc != NULL) {
|
||||
/*
|
||||
* Continue for builtins that are part of the scripting language
|
||||
*/
|
||||
if (bifunc->bfunct != dobreak && bifunc->bfunct != docontin &&
|
||||
bifunc->bfunct != doelse && bifunc->bfunct != doend &&
|
||||
bifunc->bfunct != doforeach && bifunc->bfunct != dogoto &&
|
||||
bifunc->bfunct != doif && bifunc->bfunct != dorepeat &&
|
||||
bifunc->bfunct != doswbrk && bifunc->bfunct != doswitch &&
|
||||
bifunc->bfunct != dowhile && bifunc->bfunct != dozip)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else { /* not a command */
|
||||
bifunc = NULL;
|
||||
if (noexec)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* We fork only if we are timed, or are not the end of a parenthesized
|
||||
* list and not a simple builtin function. Simple meaning one that is
|
||||
* not pipedout, niced, nohupped, or &'d. It would be nice(?) to not
|
||||
* fork in some of these cases.
|
||||
*/
|
||||
/*
|
||||
* Prevent forking cd, pushd, popd, chdir cause this will cause the
|
||||
* shell not to change dir!
|
||||
*/
|
||||
if (bifunc && (bifunc->bfunct == dochngd ||
|
||||
bifunc->bfunct == dopushd ||
|
||||
bifunc->bfunct == dopopd))
|
||||
t->t_dflg &= ~(F_NICE);
|
||||
if (((t->t_dflg & F_TIME) || ((t->t_dflg & F_NOFORK) == 0 &&
|
||||
(!bifunc || t->t_dflg &
|
||||
(F_PIPEOUT | F_AMPERSAND | F_NICE | F_NOHUP)))) ||
|
||||
/*
|
||||
* We have to fork for eval too.
|
||||
*/
|
||||
(bifunc && (t->t_dflg & (F_PIPEIN | F_PIPEOUT)) != 0 &&
|
||||
bifunc->bfunct == doeval)) {
|
||||
if (t->t_dtyp == NODE_PAREN ||
|
||||
t->t_dflg & (F_REPEAT | F_AMPERSAND) || bifunc) {
|
||||
forked++;
|
||||
/*
|
||||
* We need to block SIGCHLD here, so that if the process does
|
||||
* not die before we can set the process group
|
||||
*/
|
||||
if (wanttty >= 0 && !nosigchld) {
|
||||
sigemptyset(&nsigset);
|
||||
(void)sigaddset(&nsigset, SIGCHLD);
|
||||
(void)sigprocmask(SIG_BLOCK, &nsigset, &csigset);
|
||||
nosigchld = 1;
|
||||
}
|
||||
|
||||
pid = pfork(t, wanttty);
|
||||
if (pid == 0 && nosigchld) {
|
||||
(void)sigprocmask(SIG_SETMASK, &csigset, NULL);
|
||||
nosigchld = 0;
|
||||
}
|
||||
else if (pid != 0 && (t->t_dflg & F_AMPERSAND))
|
||||
backpid = pid;
|
||||
|
||||
}
|
||||
else {
|
||||
int ochild, osetintr, ohaderr, odidfds;
|
||||
int oSHIN, oSHOUT, oSHERR, oOLDSTD, otpgrp;
|
||||
sigset_t osigset;
|
||||
|
||||
/*
|
||||
* Prepare for the vfork by saving everything that the child
|
||||
* corrupts before it exec's. Note that in some signal
|
||||
* implementations which keep the signal info in user space
|
||||
* (e.g. Sun's) it will also be necessary to save and restore
|
||||
* the current sigaction's for the signals the child touches
|
||||
* before it exec's.
|
||||
*/
|
||||
if (wanttty >= 0 && !nosigchld && !noexec) {
|
||||
sigemptyset(&nsigset);
|
||||
(void)sigaddset(&nsigset, SIGCHLD);
|
||||
(void)sigprocmask(SIG_BLOCK, &nsigset, &csigset);
|
||||
nosigchld = 1;
|
||||
}
|
||||
sigemptyset(&nsigset);
|
||||
(void)sigaddset(&nsigset, SIGCHLD);
|
||||
(void)sigaddset(&nsigset, SIGINT);
|
||||
(void)sigprocmask(SIG_BLOCK, &nsigset, &osigset);
|
||||
ochild = child;
|
||||
osetintr = setintr;
|
||||
ohaderr = haderr;
|
||||
odidfds = didfds;
|
||||
oSHIN = SHIN;
|
||||
oSHOUT = SHOUT;
|
||||
oSHERR = SHERR;
|
||||
oOLDSTD = OLDSTD;
|
||||
otpgrp = tpgrp;
|
||||
ocsigset = csigset;
|
||||
onosigchld = nosigchld;
|
||||
Vsav = Vdp = 0;
|
||||
Vexpath = 0;
|
||||
Vt = 0;
|
||||
pid = vfork();
|
||||
|
||||
if (pid < 0) {
|
||||
(void)sigprocmask(SIG_SETMASK, &osigset, NULL);
|
||||
stderror(ERR_NOPROC);
|
||||
}
|
||||
forked++;
|
||||
if (pid) { /* parent */
|
||||
child = ochild;
|
||||
setintr = osetintr;
|
||||
haderr = ohaderr;
|
||||
didfds = odidfds;
|
||||
SHIN = oSHIN;
|
||||
SHOUT = oSHOUT;
|
||||
SHERR = oSHERR;
|
||||
OLDSTD = oOLDSTD;
|
||||
tpgrp = otpgrp;
|
||||
csigset = ocsigset;
|
||||
nosigchld = onosigchld;
|
||||
|
||||
xfree((ptr_t) Vsav);
|
||||
Vsav = 0;
|
||||
xfree((ptr_t) Vdp);
|
||||
Vdp = 0;
|
||||
xfree((ptr_t) Vexpath);
|
||||
Vexpath = 0;
|
||||
blkfree((Char **) Vt);
|
||||
Vt = 0;
|
||||
/* this is from pfork() */
|
||||
palloc(pid, t);
|
||||
(void)sigprocmask(SIG_SETMASK, &osigset, NULL);
|
||||
}
|
||||
else { /* child */
|
||||
/* this is from pfork() */
|
||||
int pgrp;
|
||||
int ignint = 0;
|
||||
|
||||
if (nosigchld) {
|
||||
(void)sigprocmask(SIG_SETMASK, &csigset, NULL);
|
||||
nosigchld = 0;
|
||||
}
|
||||
|
||||
if (setintr)
|
||||
ignint =
|
||||
(tpgrp == -1 &&
|
||||
(t->t_dflg & F_NOINTERRUPT))
|
||||
|| (gointr && eq(gointr, STRminus));
|
||||
pgrp = pcurrjob ? pcurrjob->p_jobid : getpid();
|
||||
child++;
|
||||
if (setintr) {
|
||||
setintr = 0;
|
||||
if (ignint) {
|
||||
(void)signal(SIGINT, SIG_IGN);
|
||||
(void)signal(SIGQUIT, SIG_IGN);
|
||||
}
|
||||
else {
|
||||
(void)signal(SIGINT, vffree);
|
||||
(void)signal(SIGQUIT, SIG_DFL);
|
||||
}
|
||||
|
||||
if (wanttty >= 0) {
|
||||
(void)signal(SIGTSTP, SIG_DFL);
|
||||
(void)signal(SIGTTIN, SIG_DFL);
|
||||
(void)signal(SIGTTOU, SIG_DFL);
|
||||
}
|
||||
|
||||
(void)signal(SIGTERM, parterm);
|
||||
}
|
||||
else if (tpgrp == -1 &&
|
||||
(t->t_dflg & F_NOINTERRUPT)) {
|
||||
(void)signal(SIGINT, SIG_IGN);
|
||||
(void)signal(SIGQUIT, SIG_IGN);
|
||||
}
|
||||
|
||||
pgetty(wanttty, pgrp);
|
||||
if (t->t_dflg & F_NOHUP)
|
||||
(void)signal(SIGHUP, SIG_IGN);
|
||||
if (t->t_dflg & F_NICE)
|
||||
(void)setpriority(PRIO_PROCESS, 0, t->t_nice);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (pid != 0) {
|
||||
/*
|
||||
* It would be better if we could wait for the whole job when we
|
||||
* knew the last process had been started. Pwait, in fact, does
|
||||
* wait for the whole job anyway, but this test doesn't really
|
||||
* express our intentions.
|
||||
*/
|
||||
if (didfds == 0 && t->t_dflg & F_PIPEIN) {
|
||||
(void)close(pipein[0]);
|
||||
(void)close(pipein[1]);
|
||||
}
|
||||
if ((t->t_dflg & F_PIPEOUT) == 0) {
|
||||
if (nosigchld) {
|
||||
(void)sigprocmask(SIG_SETMASK, &csigset, NULL);
|
||||
nosigchld = 0;
|
||||
}
|
||||
if ((t->t_dflg & F_AMPERSAND) == 0)
|
||||
pwait();
|
||||
}
|
||||
break;
|
||||
}
|
||||
doio(t, pipein, pipeout);
|
||||
if (t->t_dflg & F_PIPEOUT) {
|
||||
(void)close(pipeout[0]);
|
||||
(void)close(pipeout[1]);
|
||||
}
|
||||
/*
|
||||
* Perform a builtin function. If we are not forked, arrange for
|
||||
* possible stopping
|
||||
*/
|
||||
if (bifunc) {
|
||||
func(t, bifunc);
|
||||
if (forked)
|
||||
exitstat();
|
||||
break;
|
||||
}
|
||||
if (t->t_dtyp != NODE_PAREN)
|
||||
doexec(NULL, t);
|
||||
/*
|
||||
* For () commands must put new 0,1,2 in FSH* and recurse
|
||||
*/
|
||||
(void) ioctl(OLDSTD = dcopy(0, FOLDSTD), FIOCLEX, NULL);
|
||||
(void) ioctl(SHOUT = dcopy(1, FSHOUT), FIOCLEX, NULL);
|
||||
(void) ioctl(SHERR = dcopy(2, FSHERR), FIOCLEX, NULL);
|
||||
(void) close(SHIN);
|
||||
|
||||
SHIN = -1;
|
||||
didfds = 0;
|
||||
wanttty = -1;
|
||||
t->t_dspr->t_dflg |= t->t_dflg & F_NOINTERRUPT;
|
||||
execute(t->t_dspr, wanttty, NULL, NULL);
|
||||
exitstat();
|
||||
/* NOTREACHED */
|
||||
case NODE_PIPE:
|
||||
t->t_dcar->t_dflg |= F_PIPEOUT |
|
||||
(t->t_dflg & (F_PIPEIN | F_AMPERSAND | F_STDERR | F_NOINTERRUPT));
|
||||
execute(t->t_dcar, wanttty, pipein, pv);
|
||||
t->t_dcdr->t_dflg |= F_PIPEIN | (t->t_dflg &
|
||||
(F_PIPEOUT | F_AMPERSAND | F_NOFORK | F_NOINTERRUPT));
|
||||
if (wanttty > 0)
|
||||
wanttty = 0; /* got tty already */
|
||||
execute(t->t_dcdr, wanttty, pv, pipeout);
|
||||
break;
|
||||
case NODE_LIST:
|
||||
if (t->t_dcar) {
|
||||
t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT;
|
||||
execute(t->t_dcar, wanttty, NULL, NULL);
|
||||
/*
|
||||
* In strange case of A&B make a new job after A
|
||||
*/
|
||||
if (t->t_dcar->t_dflg & F_AMPERSAND && t->t_dcdr &&
|
||||
(t->t_dcdr->t_dflg & F_AMPERSAND) == 0)
|
||||
pendjob();
|
||||
}
|
||||
if (t->t_dcdr) {
|
||||
t->t_dcdr->t_dflg |= t->t_dflg &
|
||||
(F_NOFORK | F_NOINTERRUPT);
|
||||
execute(t->t_dcdr, wanttty, NULL, NULL);
|
||||
}
|
||||
break;
|
||||
case NODE_OR:
|
||||
case NODE_AND:
|
||||
if (t->t_dcar) {
|
||||
t->t_dcar->t_dflg |= t->t_dflg & F_NOINTERRUPT;
|
||||
execute(t->t_dcar, wanttty, NULL, NULL);
|
||||
if ((getn(value(STRstatus)) == 0) !=
|
||||
(t->t_dtyp == NODE_AND))
|
||||
return;
|
||||
}
|
||||
if (t->t_dcdr) {
|
||||
t->t_dcdr->t_dflg |= t->t_dflg &
|
||||
(F_NOFORK | F_NOINTERRUPT);
|
||||
execute(t->t_dcdr, wanttty, NULL, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Fall through for all breaks from switch
|
||||
*
|
||||
* If there will be no more executions of this command, flush all file
|
||||
* descriptors. Places that turn on the F_REPEAT bit are responsible for
|
||||
* doing donefds after the last re-execution
|
||||
*/
|
||||
if (didfds && !(t->t_dflg & F_REPEAT))
|
||||
donefds();
|
||||
}
|
||||
|
||||
static void
|
||||
vffree(int i)
|
||||
{
|
||||
Char **v;
|
||||
|
||||
if ((v = gargv) != NULL) {
|
||||
gargv = 0;
|
||||
xfree((ptr_t) v);
|
||||
}
|
||||
if ((v = pargv) != NULL) {
|
||||
pargv = 0;
|
||||
xfree((ptr_t) v);
|
||||
}
|
||||
_exit(i);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Expand and glob the words after an i/o redirection.
|
||||
* If more than one word is generated, then update the command vector.
|
||||
*
|
||||
* This is done differently in all the shells:
|
||||
* 1. in the bourne shell and ksh globbing is not performed
|
||||
* 2. Bash/csh say ambiguous
|
||||
* 3. zsh does i/o to/from all the files
|
||||
* 4. itcsh concatenates the words.
|
||||
*
|
||||
* I don't know what is best to do. I think that Ambiguous is better
|
||||
* than restructuring the command vector, because the user can get
|
||||
* unexpected results. In any case, the command vector restructuring
|
||||
* code is present and the user can choose it by setting noambiguous
|
||||
*/
|
||||
static Char *
|
||||
splicepipe(struct command *t, Char *cp /* word after < or > */)
|
||||
{
|
||||
Char *blk[2];
|
||||
|
||||
if (adrof(STRnoambiguous)) {
|
||||
Char **pv;
|
||||
|
||||
blk[0] = Dfix1(cp); /* expand $ */
|
||||
blk[1] = NULL;
|
||||
|
||||
gflag = 0, tglob(blk);
|
||||
if (gflag) {
|
||||
pv = globall(blk);
|
||||
if (pv == NULL) {
|
||||
setname(vis_str(blk[0]));
|
||||
xfree((ptr_t) blk[0]);
|
||||
stderror(ERR_NAME | ERR_NOMATCH);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
gargv = NULL;
|
||||
if (pv[1] != NULL) { /* we need to fix the command vector */
|
||||
Char **av = blkspl(t->t_dcom, &pv[1]);
|
||||
xfree((ptr_t) t->t_dcom);
|
||||
t->t_dcom = av;
|
||||
}
|
||||
xfree((ptr_t) blk[0]);
|
||||
blk[0] = pv[0];
|
||||
xfree((ptr_t) pv);
|
||||
}
|
||||
}
|
||||
else {
|
||||
blk[0] = globone(blk[1] = Dfix1(cp), G_ERROR);
|
||||
xfree((ptr_t) blk[1]);
|
||||
}
|
||||
return(blk[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform io redirection.
|
||||
* We may or maynot be forked here.
|
||||
*/
|
||||
static void
|
||||
doio(struct command *t, int *pipein, int *pipeout)
|
||||
{
|
||||
Char *cp;
|
||||
int fd, flags;
|
||||
|
||||
flags = t->t_dflg;
|
||||
if (didfds || (flags & F_REPEAT))
|
||||
return;
|
||||
if ((flags & F_READ) == 0) {/* F_READ already done */
|
||||
if (t->t_dlef) {
|
||||
char tmp[MAXPATHLEN+1];
|
||||
|
||||
/*
|
||||
* so < /dev/std{in,out,err} work
|
||||
*/
|
||||
(void)dcopy(SHIN, 0);
|
||||
(void)dcopy(SHOUT, 1);
|
||||
(void)dcopy(SHERR, 2);
|
||||
cp = splicepipe(t, t->t_dlef);
|
||||
(void)strlcpy(tmp, short2str(cp), sizeof(tmp));
|
||||
xfree((ptr_t) cp);
|
||||
if ((fd = open(tmp, O_RDONLY)) < 0) {
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
/* NOTREACHED */
|
||||
}
|
||||
(void)dmove(fd, 0);
|
||||
}
|
||||
else if (flags & F_PIPEIN) {
|
||||
(void)close(0);
|
||||
(void)dup(pipein[0]);
|
||||
(void)close(pipein[0]);
|
||||
(void)close(pipein[1]);
|
||||
}
|
||||
else if ((flags & F_NOINTERRUPT) && tpgrp == -1) {
|
||||
(void)close(0);
|
||||
(void)open(_PATH_DEVNULL, O_RDONLY);
|
||||
}
|
||||
else {
|
||||
(void)close(0);
|
||||
(void)dup(OLDSTD);
|
||||
(void)ioctl(0, FIONCLEX, NULL);
|
||||
}
|
||||
}
|
||||
if (t->t_drit) {
|
||||
char tmp[MAXPATHLEN+1];
|
||||
|
||||
cp = splicepipe(t, t->t_drit);
|
||||
(void)strlcpy(tmp, short2str(cp), sizeof(tmp));
|
||||
xfree((ptr_t) cp);
|
||||
/*
|
||||
* so > /dev/std{out,err} work
|
||||
*/
|
||||
(void)dcopy(SHOUT, 1);
|
||||
(void)dcopy(SHERR, 2);
|
||||
if ((flags & F_APPEND) &&
|
||||
#ifdef O_APPEND
|
||||
(fd = open(tmp, O_WRONLY | O_APPEND)) >= 0);
|
||||
#else
|
||||
(fd = open(tmp, O_WRONLY)) >= 0)
|
||||
(void)lseek(1, (off_t) 0, SEEK_END);
|
||||
#endif
|
||||
else {
|
||||
if (!(flags & F_OVERWRITE) && adrof(STRnoclobber)) {
|
||||
if (flags & F_APPEND) {
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
/* NOTREACHED */
|
||||
}
|
||||
chkclob(tmp);
|
||||
}
|
||||
if ((fd = open(tmp, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {
|
||||
stderror(ERR_SYSTEM, tmp, strerror(errno));
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
(void)dmove(fd, 1);
|
||||
}
|
||||
else if (flags & F_PIPEOUT) {
|
||||
(void)close(1);
|
||||
(void)dup(pipeout[1]);
|
||||
}
|
||||
else {
|
||||
(void)close(1);
|
||||
(void)dup(SHOUT);
|
||||
(void)ioctl(1, FIONCLEX, NULL);
|
||||
}
|
||||
|
||||
(void)close(2);
|
||||
if (flags & F_STDERR) {
|
||||
(void)dup(1);
|
||||
}
|
||||
else {
|
||||
(void)dup(SHERR);
|
||||
(void)ioctl(2, FIONCLEX, NULL);
|
||||
}
|
||||
didfds = 1;
|
||||
}
|
||||
|
||||
void
|
||||
mypipe(int *pv)
|
||||
{
|
||||
if (pipe(pv) < 0)
|
||||
goto oops;
|
||||
pv[0] = dmove(pv[0], -1);
|
||||
pv[1] = dmove(pv[1], -1);
|
||||
if (pv[0] >= 0 && pv[1] >= 0)
|
||||
return;
|
||||
oops:
|
||||
stderror(ERR_PIPE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static void
|
||||
chkclob(char *cp)
|
||||
{
|
||||
struct stat stb;
|
||||
|
||||
if (stat(cp, &stb) < 0)
|
||||
return;
|
||||
if (S_ISCHR(stb.st_mode))
|
||||
return;
|
||||
stderror(ERR_EXISTS, cp);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
820
bin/csh/set.c
Normal file
820
bin/csh/set.c
Normal file
@@ -0,0 +1,820 @@
|
||||
/* $NetBSD: set.c,v 1.33 2013/07/16 17:47:43 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)set.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: set.c,v 1.33 2013/07/16 17:47:43 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef SHORT_STRINGS
|
||||
#include <string.h>
|
||||
#endif /* SHORT_STRINGS */
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
static Char *getinx(Char *, int *);
|
||||
static void asx(Char *, int, Char *);
|
||||
static struct varent *getvx(Char *, int);
|
||||
static Char *xset(Char *, Char ***);
|
||||
static Char *operate(int, Char *, Char *);
|
||||
static void putn1(int);
|
||||
static struct varent *madrof(Char *, struct varent *);
|
||||
static void unsetv1(struct varent *);
|
||||
static void exportpath(Char **);
|
||||
static void balance(struct varent *, int, int);
|
||||
|
||||
/*
|
||||
* C Shell
|
||||
*/
|
||||
|
||||
static void
|
||||
update_vars(Char *vp)
|
||||
{
|
||||
if (eq(vp, STRpath)) {
|
||||
struct varent *pt = adrof(STRpath);
|
||||
if (pt == NULL)
|
||||
stderror(ERR_NAME | ERR_UNDVAR);
|
||||
else {
|
||||
exportpath(pt->vec);
|
||||
dohash(NULL, NULL);
|
||||
}
|
||||
}
|
||||
else if (eq(vp, STRhistchars)) {
|
||||
Char *pn = value(STRhistchars);
|
||||
|
||||
HIST = *pn++;
|
||||
HISTSUB = *pn;
|
||||
}
|
||||
else if (eq(vp, STRuser)) {
|
||||
Setenv(STRUSER, value(vp));
|
||||
Setenv(STRLOGNAME, value(vp));
|
||||
}
|
||||
else if (eq(vp, STRwordchars)) {
|
||||
word_chars = value(vp);
|
||||
}
|
||||
else if (eq(vp, STRterm))
|
||||
Setenv(STRTERM, value(vp));
|
||||
else if (eq(vp, STRhome)) {
|
||||
Char *cp;
|
||||
|
||||
cp = Strsave(value(vp)); /* get the old value back */
|
||||
|
||||
/*
|
||||
* convert to canonical pathname (possibly resolving symlinks)
|
||||
*/
|
||||
cp = dcanon(cp, cp);
|
||||
|
||||
set(vp, Strsave(cp)); /* have to save the new val */
|
||||
|
||||
/* and now mirror home with HOME */
|
||||
Setenv(STRHOME, cp);
|
||||
/* fix directory stack for new tilde home */
|
||||
dtilde();
|
||||
xfree((ptr_t)cp);
|
||||
}
|
||||
#ifdef FILEC
|
||||
else if (eq(vp, STRfilec))
|
||||
filec = 1;
|
||||
#endif
|
||||
#ifdef EDIT
|
||||
else if (eq(vp, STRedit)) {
|
||||
HistEvent ev;
|
||||
editing = 1;
|
||||
el = el_init_fd(getprogname(), cshin, cshout, csherr,
|
||||
SHIN, SHOUT, SHERR);
|
||||
el_set(el, EL_EDITOR, "emacs");
|
||||
el_set(el, EL_PROMPT, printpromptstr);
|
||||
hi = history_init();
|
||||
history(hi, &ev, H_SETSIZE, getn(value(STRhistory)));
|
||||
loadhist(Histlist.Hnext);
|
||||
el_set(el, EL_HIST, history, hi);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
doset(Char **v, struct command *t)
|
||||
{
|
||||
Char op, *p, **vecp, *vp;
|
||||
int subscr = 0; /* XXX: GCC */
|
||||
int hadsub;
|
||||
|
||||
v++;
|
||||
p = *v++;
|
||||
if (p == 0) {
|
||||
prvars();
|
||||
return;
|
||||
}
|
||||
do {
|
||||
hadsub = 0;
|
||||
vp = p;
|
||||
if (letter(*p))
|
||||
for (; alnum(*p); p++)
|
||||
continue;
|
||||
if (vp == p || !letter(*vp))
|
||||
stderror(ERR_NAME | ERR_VARBEGIN);
|
||||
if ((p - vp) > MAXVARLEN)
|
||||
stderror(ERR_NAME | ERR_VARTOOLONG);
|
||||
if (*p == '[') {
|
||||
hadsub++;
|
||||
p = getinx(p, &subscr);
|
||||
}
|
||||
if ((op = *p) != '\0') {
|
||||
*p++ = 0;
|
||||
if (*p == 0 && *v && **v == '(')
|
||||
p = *v++;
|
||||
}
|
||||
else if (*v && eq(*v, STRequal)) {
|
||||
op = '=', v++;
|
||||
if (*v)
|
||||
p = *v++;
|
||||
}
|
||||
if (op && op != '=')
|
||||
stderror(ERR_NAME | ERR_SYNTAX);
|
||||
if (eq(p, STRLparen)) {
|
||||
Char **e = v;
|
||||
|
||||
if (hadsub)
|
||||
stderror(ERR_NAME | ERR_SYNTAX);
|
||||
for (;;) {
|
||||
if (!*e)
|
||||
stderror(ERR_NAME | ERR_MISSING, ')');
|
||||
if (**e == ')')
|
||||
break;
|
||||
e++;
|
||||
}
|
||||
p = *e;
|
||||
*e = 0;
|
||||
vecp = saveblk(v);
|
||||
set1(vp, vecp, &shvhed);
|
||||
*e = p;
|
||||
v = e + 1;
|
||||
}
|
||||
else if (hadsub)
|
||||
asx(vp, subscr, Strsave(p));
|
||||
else
|
||||
set(vp, Strsave(p));
|
||||
update_vars(vp);
|
||||
} while ((p = *v++) != NULL);
|
||||
}
|
||||
|
||||
static Char *
|
||||
getinx(Char *cp, int *ip)
|
||||
{
|
||||
*ip = 0;
|
||||
*cp++ = 0;
|
||||
while (*cp && Isdigit(*cp))
|
||||
*ip = *ip * 10 + *cp++ - '0';
|
||||
if (*cp++ != ']')
|
||||
stderror(ERR_NAME | ERR_SUBSCRIPT);
|
||||
return (cp);
|
||||
}
|
||||
|
||||
static void
|
||||
asx(Char *vp, int subscr, Char *p)
|
||||
{
|
||||
struct varent *v;
|
||||
|
||||
v = getvx(vp, subscr);
|
||||
xfree((ptr_t) v->vec[subscr - 1]);
|
||||
v->vec[subscr - 1] = globone(p, G_APPEND);
|
||||
}
|
||||
|
||||
static struct varent *
|
||||
getvx(Char *vp, int subscr)
|
||||
{
|
||||
struct varent *v;
|
||||
|
||||
v = adrof(vp);
|
||||
if (v == 0)
|
||||
udvar(vp);
|
||||
if (subscr < 1 || subscr > blklen(v->vec))
|
||||
stderror(ERR_NAME | ERR_RANGE);
|
||||
return (v);
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dolet(Char **v, struct command *t)
|
||||
{
|
||||
Char c, op, *p, *vp;
|
||||
int subscr = 0; /* XXX: GCC */
|
||||
int hadsub;
|
||||
|
||||
v++;
|
||||
p = *v++;
|
||||
if (p == 0) {
|
||||
prvars();
|
||||
return;
|
||||
}
|
||||
do {
|
||||
hadsub = 0;
|
||||
vp = p;
|
||||
if (letter(*p))
|
||||
for (; alnum(*p); p++)
|
||||
continue;
|
||||
if (vp == p || !letter(*vp))
|
||||
stderror(ERR_NAME | ERR_VARBEGIN);
|
||||
if ((p - vp) > MAXVARLEN)
|
||||
stderror(ERR_NAME | ERR_VARTOOLONG);
|
||||
if (*p == '[') {
|
||||
hadsub++;
|
||||
p = getinx(p, &subscr);
|
||||
}
|
||||
if (*p == 0 && *v)
|
||||
p = *v++;
|
||||
if ((op = *p) != '\0')
|
||||
*p++ = 0;
|
||||
else
|
||||
stderror(ERR_NAME | ERR_ASSIGN);
|
||||
|
||||
if (*p == '\0' && *v == NULL)
|
||||
stderror(ERR_NAME | ERR_ASSIGN);
|
||||
|
||||
vp = Strsave(vp);
|
||||
if (op == '=') {
|
||||
c = '=';
|
||||
p = xset(p, &v);
|
||||
}
|
||||
else {
|
||||
c = *p++;
|
||||
if (any("+-", c)) {
|
||||
if (c != op || *p)
|
||||
stderror(ERR_NAME | ERR_UNKNOWNOP);
|
||||
p = Strsave(STR1);
|
||||
}
|
||||
else {
|
||||
if (any("<>", op)) {
|
||||
if (c != op)
|
||||
stderror(ERR_NAME | ERR_UNKNOWNOP);
|
||||
c = *p++;
|
||||
stderror(ERR_NAME | ERR_SYNTAX);
|
||||
}
|
||||
if (c != '=')
|
||||
stderror(ERR_NAME | ERR_UNKNOWNOP);
|
||||
p = xset(p, &v);
|
||||
}
|
||||
}
|
||||
if (op == '=') {
|
||||
if (hadsub)
|
||||
asx(vp, subscr, p);
|
||||
else
|
||||
set(vp, p);
|
||||
} else if (hadsub) {
|
||||
struct varent *gv = getvx(vp, subscr);
|
||||
|
||||
asx(vp, subscr, operate(op, gv->vec[subscr - 1], p));
|
||||
}
|
||||
else
|
||||
set(vp, operate(op, value(vp), p));
|
||||
if (eq(vp, STRpath)) {
|
||||
struct varent *pt = adrof(STRpath);
|
||||
if (pt == NULL)
|
||||
stderror(ERR_NAME | ERR_UNDVAR);
|
||||
else {
|
||||
exportpath(pt->vec);
|
||||
dohash(NULL, NULL);
|
||||
}
|
||||
}
|
||||
xfree((ptr_t) vp);
|
||||
if (c != '=')
|
||||
xfree((ptr_t) p);
|
||||
} while ((p = *v++) != NULL);
|
||||
}
|
||||
|
||||
static Char *
|
||||
xset(Char *cp, Char ***vp)
|
||||
{
|
||||
Char *dp;
|
||||
|
||||
if (*cp) {
|
||||
dp = Strsave(cp);
|
||||
--(*vp);
|
||||
xfree((ptr_t) ** vp);
|
||||
**vp = dp;
|
||||
}
|
||||
return (putn(expr(vp)));
|
||||
}
|
||||
|
||||
static Char *
|
||||
operate(int op, Char *vp, Char *p)
|
||||
{
|
||||
Char opr[2], **v, *vec[5], **vecp;
|
||||
int i;
|
||||
|
||||
v = vec;
|
||||
vecp = v;
|
||||
if (op != '=') {
|
||||
if (*vp)
|
||||
*v++ = vp;
|
||||
opr[0] = (Char)op;
|
||||
opr[1] = 0;
|
||||
*v++ = opr;
|
||||
if (op == '<' || op == '>')
|
||||
*v++ = opr;
|
||||
}
|
||||
*v++ = p;
|
||||
*v++ = 0;
|
||||
i = expr(&vecp);
|
||||
if (*vecp)
|
||||
stderror(ERR_NAME | ERR_EXPRESSION);
|
||||
return (putn(i));
|
||||
}
|
||||
|
||||
static Char *putp;
|
||||
|
||||
Char *
|
||||
putn(int n)
|
||||
{
|
||||
static Char numbers[15];
|
||||
|
||||
putp = numbers;
|
||||
if (n < 0) {
|
||||
n = -n;
|
||||
*putp++ = '-';
|
||||
}
|
||||
if ((unsigned int)n == 0x80000000U) {
|
||||
*putp++ = '2';
|
||||
n = 147483648;
|
||||
}
|
||||
putn1(n);
|
||||
*putp = 0;
|
||||
return (Strsave(numbers));
|
||||
}
|
||||
|
||||
static void
|
||||
putn1(int n)
|
||||
{
|
||||
if (n > 9)
|
||||
putn1(n / 10);
|
||||
*putp++ = (Char)(n % 10 + '0');
|
||||
}
|
||||
|
||||
int
|
||||
getn(Char *cp)
|
||||
{
|
||||
int n, sign;
|
||||
|
||||
sign = 0;
|
||||
if (cp[0] == '+' && cp[1])
|
||||
cp++;
|
||||
if (*cp == '-') {
|
||||
sign++;
|
||||
cp++;
|
||||
if (!Isdigit(*cp))
|
||||
stderror(ERR_NAME | ERR_BADNUM);
|
||||
}
|
||||
n = 0;
|
||||
while (Isdigit(*cp))
|
||||
n = n * 10 + *cp++ - '0';
|
||||
if (*cp)
|
||||
stderror(ERR_NAME | ERR_BADNUM);
|
||||
return (sign ? -n : n);
|
||||
}
|
||||
|
||||
Char *
|
||||
value1(Char *var, struct varent *head)
|
||||
{
|
||||
struct varent *vp;
|
||||
|
||||
vp = adrof1(var, head);
|
||||
return (vp == 0 || vp->vec[0] == 0 ? STRNULL : vp->vec[0]);
|
||||
}
|
||||
|
||||
static struct varent *
|
||||
madrof(Char *pat, struct varent *vp)
|
||||
{
|
||||
struct varent *vp1;
|
||||
|
||||
for (; vp; vp = vp->v_right) {
|
||||
if (vp->v_left && (vp1 = madrof(pat, vp->v_left)))
|
||||
return vp1;
|
||||
if (Gmatch(vp->v_name, pat))
|
||||
return vp;
|
||||
}
|
||||
return vp;
|
||||
}
|
||||
|
||||
struct varent *
|
||||
adrof1(Char *name, struct varent *v)
|
||||
{
|
||||
int cmp;
|
||||
|
||||
v = v->v_left;
|
||||
while (v && ((cmp = *name - *v->v_name) ||
|
||||
(cmp = Strcmp(name, v->v_name))))
|
||||
if (cmp < 0)
|
||||
v = v->v_left;
|
||||
else
|
||||
v = v->v_right;
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
* The caller is responsible for putting value in a safe place
|
||||
*/
|
||||
void
|
||||
set(Char *var, Char *val)
|
||||
{
|
||||
Char **vec;
|
||||
|
||||
vec = xmalloc(2 * sizeof(*vec));
|
||||
vec[0] = val;
|
||||
vec[1] = 0;
|
||||
set1(var, vec, &shvhed);
|
||||
}
|
||||
|
||||
void
|
||||
set1(Char *var, Char **vec, struct varent *head)
|
||||
{
|
||||
Char **oldv;
|
||||
|
||||
oldv = vec;
|
||||
gflag = 0;
|
||||
tglob(oldv);
|
||||
if (gflag) {
|
||||
vec = globall(oldv);
|
||||
if (vec == 0) {
|
||||
blkfree(oldv);
|
||||
stderror(ERR_NAME | ERR_NOMATCH);
|
||||
}
|
||||
blkfree(oldv);
|
||||
gargv = 0;
|
||||
}
|
||||
setq(var, vec, head);
|
||||
}
|
||||
|
||||
void
|
||||
setq(Char *name, Char **vec, struct varent *p)
|
||||
{
|
||||
struct varent *c;
|
||||
int f;
|
||||
|
||||
f = 0; /* tree hangs off the header's left link */
|
||||
while ((c = p->v_link[f]) != NULL) {
|
||||
if ((f = *name - *c->v_name) == 0 &&
|
||||
(f = Strcmp(name, c->v_name)) == 0) {
|
||||
blkfree(c->vec);
|
||||
goto found;
|
||||
}
|
||||
p = c;
|
||||
f = f > 0;
|
||||
}
|
||||
p->v_link[f] = c = xmalloc(sizeof(*c));
|
||||
c->v_name = Strsave(name);
|
||||
c->v_bal = 0;
|
||||
c->v_left = c->v_right = 0;
|
||||
c->v_parent = p;
|
||||
balance(p, f, 0);
|
||||
found:
|
||||
trim(c->vec = vec);
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
unset(Char **v, struct command *t)
|
||||
{
|
||||
unset1(v, &shvhed);
|
||||
if (adrof(STRhistchars) == 0) {
|
||||
HIST = '!';
|
||||
HISTSUB = '^';
|
||||
}
|
||||
else if (adrof(STRwordchars) == 0)
|
||||
word_chars = STR_WORD_CHARS;
|
||||
#ifdef FILEC
|
||||
else if (adrof(STRfilec) == 0)
|
||||
filec = 0;
|
||||
#endif
|
||||
#ifdef EDIT
|
||||
else if (adrof(STRedit) == 0) {
|
||||
el_end(el);
|
||||
history_end(hi);
|
||||
el = NULL;
|
||||
hi = NULL;
|
||||
editing = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
unset1(Char *v[], struct varent *head)
|
||||
{
|
||||
struct varent *vp;
|
||||
int cnt;
|
||||
|
||||
while (*++v) {
|
||||
cnt = 0;
|
||||
while ((vp = madrof(*v, head->v_left)) != NULL)
|
||||
unsetv1(vp), cnt++;
|
||||
if (cnt == 0)
|
||||
setname(vis_str(*v));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
unsetv(Char *var)
|
||||
{
|
||||
struct varent *vp;
|
||||
|
||||
if ((vp = adrof1(var, &shvhed)) == 0)
|
||||
udvar(var);
|
||||
unsetv1(vp);
|
||||
}
|
||||
|
||||
static void
|
||||
unsetv1(struct varent *p)
|
||||
{
|
||||
struct varent *c, *pp;
|
||||
int f;
|
||||
|
||||
/*
|
||||
* Free associated memory first to avoid complications.
|
||||
*/
|
||||
blkfree(p->vec);
|
||||
xfree((ptr_t) p->v_name);
|
||||
/*
|
||||
* If p is missing one child, then we can move the other into where p is.
|
||||
* Otherwise, we find the predecessor of p, which is guaranteed to have no
|
||||
* right child, copy it into p, and move its left child into it.
|
||||
*/
|
||||
if (p->v_right == 0)
|
||||
c = p->v_left;
|
||||
else if (p->v_left == 0)
|
||||
c = p->v_right;
|
||||
else {
|
||||
for (c = p->v_left; c->v_right; c = c->v_right)
|
||||
continue;
|
||||
p->v_name = c->v_name;
|
||||
p->vec = c->vec;
|
||||
p = c;
|
||||
c = p->v_left;
|
||||
}
|
||||
/*
|
||||
* Move c into where p is.
|
||||
*/
|
||||
pp = p->v_parent;
|
||||
f = pp->v_right == p;
|
||||
if ((pp->v_link[f] = c) != NULL)
|
||||
c->v_parent = pp;
|
||||
/*
|
||||
* Free the deleted node, and rebalance.
|
||||
*/
|
||||
xfree((ptr_t) p);
|
||||
balance(pp, f, 1);
|
||||
}
|
||||
|
||||
void
|
||||
setNS(Char *cp)
|
||||
{
|
||||
set(cp, Strsave(STRNULL));
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
shift(Char **v, struct command *t)
|
||||
{
|
||||
struct varent *argv;
|
||||
Char *name;
|
||||
|
||||
v++;
|
||||
name = *v;
|
||||
if (name == 0)
|
||||
name = STRargv;
|
||||
else
|
||||
(void) strip(name);
|
||||
argv = adrof(name);
|
||||
if (argv == 0)
|
||||
udvar(name);
|
||||
if (argv->vec[0] == 0)
|
||||
stderror(ERR_NAME | ERR_NOMORE);
|
||||
lshift(argv->vec, 1);
|
||||
update_vars(name);
|
||||
}
|
||||
|
||||
static void
|
||||
exportpath(Char **val)
|
||||
{
|
||||
Char exppath[BUFSIZE];
|
||||
|
||||
exppath[0] = 0;
|
||||
if (val)
|
||||
while (*val) {
|
||||
if (Strlen(*val) + Strlen(exppath) + 2 > BUFSIZE) {
|
||||
(void)fprintf(csherr,
|
||||
"Warning: ridiculously long PATH truncated\n");
|
||||
break;
|
||||
}
|
||||
(void)Strcat(exppath, *val++);
|
||||
if (*val == 0 || eq(*val, STRRparen))
|
||||
break;
|
||||
(void)Strcat(exppath, STRcolon);
|
||||
}
|
||||
Setenv(STRPATH, exppath);
|
||||
}
|
||||
|
||||
#ifndef lint
|
||||
/*
|
||||
* Lint thinks these have null effect
|
||||
*/
|
||||
/* macros to do single rotations on node p */
|
||||
#define rright(p) (\
|
||||
t = (p)->v_left,\
|
||||
(t)->v_parent = (p)->v_parent,\
|
||||
((p)->v_left = t->v_right) ? (t->v_right->v_parent = (p)) : 0,\
|
||||
(t->v_right = (p))->v_parent = t,\
|
||||
(p) = t)
|
||||
#define rleft(p) (\
|
||||
t = (p)->v_right,\
|
||||
(t)->v_parent = (p)->v_parent,\
|
||||
((p)->v_right = t->v_left) ? (t->v_left->v_parent = (p)) : 0,\
|
||||
(t->v_left = (p))->v_parent = t,\
|
||||
(p) = t)
|
||||
#else
|
||||
struct varent *
|
||||
rleft(struct varent *p)
|
||||
{
|
||||
return (p);
|
||||
}
|
||||
struct varent *
|
||||
rright(struct varent *p)
|
||||
{
|
||||
return (p);
|
||||
}
|
||||
#endif /* ! lint */
|
||||
|
||||
|
||||
/*
|
||||
* Rebalance a tree, starting at p and up.
|
||||
* F == 0 means we've come from p's left child.
|
||||
* D == 1 means we've just done a delete, otherwise an insert.
|
||||
*/
|
||||
static void
|
||||
balance(struct varent *p, int f, int d)
|
||||
{
|
||||
struct varent *pp;
|
||||
|
||||
#ifndef lint
|
||||
struct varent *t; /* used by the rotate macros */
|
||||
|
||||
#endif
|
||||
int ff;
|
||||
|
||||
/*
|
||||
* Ok, from here on, p is the node we're operating on; pp is its parent; f
|
||||
* is the branch of p from which we have come; ff is the branch of pp which
|
||||
* is p.
|
||||
*/
|
||||
for (; (pp = p->v_parent) != NULL; p = pp, f = ff) {
|
||||
ff = pp->v_right == p;
|
||||
if (f ^ d) { /* right heavy */
|
||||
switch (p->v_bal) {
|
||||
case -1: /* was left heavy */
|
||||
p->v_bal = 0;
|
||||
break;
|
||||
case 0: /* was balanced */
|
||||
p->v_bal = 1;
|
||||
break;
|
||||
case 1: /* was already right heavy */
|
||||
switch (p->v_right->v_bal) {
|
||||
case 1: /* single rotate */
|
||||
pp->v_link[ff] = rleft(p);
|
||||
p->v_left->v_bal = 0;
|
||||
p->v_bal = 0;
|
||||
break;
|
||||
case 0: /* single rotate */
|
||||
pp->v_link[ff] = rleft(p);
|
||||
p->v_left->v_bal = 1;
|
||||
p->v_bal = -1;
|
||||
break;
|
||||
case -1: /* double rotate */
|
||||
(void) rright(p->v_right);
|
||||
pp->v_link[ff] = rleft(p);
|
||||
p->v_left->v_bal =
|
||||
p->v_bal < 1 ? 0 : -1;
|
||||
p->v_right->v_bal =
|
||||
p->v_bal > -1 ? 0 : 1;
|
||||
p->v_bal = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else { /* left heavy */
|
||||
switch (p->v_bal) {
|
||||
case 1: /* was right heavy */
|
||||
p->v_bal = 0;
|
||||
break;
|
||||
case 0: /* was balanced */
|
||||
p->v_bal = -1;
|
||||
break;
|
||||
case -1: /* was already left heavy */
|
||||
switch (p->v_left->v_bal) {
|
||||
case -1: /* single rotate */
|
||||
pp->v_link[ff] = rright(p);
|
||||
p->v_right->v_bal = 0;
|
||||
p->v_bal = 0;
|
||||
break;
|
||||
case 0: /* single rotate */
|
||||
pp->v_link[ff] = rright(p);
|
||||
p->v_right->v_bal = -1;
|
||||
p->v_bal = 1;
|
||||
break;
|
||||
case 1: /* double rotate */
|
||||
(void) rleft(p->v_left);
|
||||
pp->v_link[ff] = rright(p);
|
||||
p->v_left->v_bal =
|
||||
p->v_bal < 1 ? 0 : -1;
|
||||
p->v_right->v_bal =
|
||||
p->v_bal > -1 ? 0 : 1;
|
||||
p->v_bal = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If from insert, then we terminate when p is balanced. If from
|
||||
* delete, then we terminate when p is unbalanced.
|
||||
*/
|
||||
if ((p->v_bal == 0) ^ d)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
plist(struct varent *p)
|
||||
{
|
||||
struct varent *c;
|
||||
sigset_t nsigset;
|
||||
int len;
|
||||
|
||||
if (setintr) {
|
||||
sigemptyset(&nsigset);
|
||||
(void)sigaddset(&nsigset, SIGINT);
|
||||
(void)sigprocmask(SIG_UNBLOCK, &nsigset, NULL);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
while (p->v_left)
|
||||
p = p->v_left;
|
||||
x:
|
||||
if (p->v_parent == 0) /* is it the header? */
|
||||
return;
|
||||
len = blklen(p->vec);
|
||||
(void)fprintf(cshout, "%s\t", short2str(p->v_name));
|
||||
if (len != 1)
|
||||
(void)fputc('(', cshout);
|
||||
blkpr(cshout, p->vec);
|
||||
if (len != 1)
|
||||
(void)fputc(')', cshout);
|
||||
(void)fputc('\n', cshout);
|
||||
if (p->v_right) {
|
||||
p = p->v_right;
|
||||
continue;
|
||||
}
|
||||
do {
|
||||
c = p;
|
||||
p = p->v_parent;
|
||||
} while (p->v_right == c);
|
||||
goto x;
|
||||
}
|
||||
}
|
||||
441
bin/csh/str.c
Normal file
441
bin/csh/str.c
Normal file
@@ -0,0 +1,441 @@
|
||||
/* $NetBSD: str.c,v 1.15 2013/07/16 17:47:43 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)str.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: str.c,v 1.15 2013/07/16 17:47:43 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#define MALLOC_INCR 128
|
||||
|
||||
/*
|
||||
* tc.str.c: Short string package
|
||||
* This has been a lesson of how to write buggy code!
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <vis.h>
|
||||
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
|
||||
#ifdef SHORT_STRINGS
|
||||
|
||||
Char **
|
||||
blk2short(char **src)
|
||||
{
|
||||
Char **dst, **sdst;
|
||||
size_t n;
|
||||
|
||||
/*
|
||||
* Count
|
||||
*/
|
||||
for (n = 0; src[n] != NULL; n++)
|
||||
continue;
|
||||
sdst = dst = xmalloc((size_t)((n + 1) * sizeof(*dst)));
|
||||
|
||||
for (; *src != NULL; src++)
|
||||
*dst++ = SAVE(*src);
|
||||
*dst = NULL;
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
char **
|
||||
short2blk(Char *const *src)
|
||||
{
|
||||
char **dst, **sdst;
|
||||
size_t n;
|
||||
|
||||
/*
|
||||
* Count
|
||||
*/
|
||||
for (n = 0; src[n] != NULL; n++)
|
||||
continue;
|
||||
sdst = dst = xmalloc((size_t)((n + 1) * sizeof(*dst)));
|
||||
|
||||
for (; *src != NULL; src++)
|
||||
*dst++ = strsave(short2str(*src));
|
||||
*dst = NULL;
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
Char *
|
||||
str2short(const char *src)
|
||||
{
|
||||
static Char *sdst;
|
||||
Char *dst, *edst;
|
||||
static size_t dstsize = 0;
|
||||
|
||||
if (src == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (sdst == (NULL)) {
|
||||
dstsize = MALLOC_INCR;
|
||||
sdst = xmalloc((size_t)dstsize * sizeof(*sdst));
|
||||
}
|
||||
|
||||
dst = sdst;
|
||||
edst = &dst[dstsize];
|
||||
while (*src) {
|
||||
*dst++ = (Char) ((unsigned char) *src++);
|
||||
if (dst == edst) {
|
||||
dstsize += MALLOC_INCR;
|
||||
sdst = xrealloc((ptr_t)sdst,
|
||||
(size_t)dstsize * sizeof(*sdst));
|
||||
edst = &sdst[dstsize];
|
||||
dst = &edst[-MALLOC_INCR];
|
||||
}
|
||||
}
|
||||
*dst = 0;
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
char *
|
||||
short2str(const Char *src)
|
||||
{
|
||||
static char *sdst = NULL;
|
||||
static size_t dstsize = 0;
|
||||
char *dst, *edst;
|
||||
|
||||
if (src == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (sdst == NULL) {
|
||||
dstsize = MALLOC_INCR;
|
||||
sdst = xmalloc((size_t)dstsize * sizeof(*sdst));
|
||||
}
|
||||
dst = sdst;
|
||||
edst = &dst[dstsize];
|
||||
while (*src) {
|
||||
*dst++ = (char) *src++;
|
||||
if (dst == edst) {
|
||||
dstsize += MALLOC_INCR;
|
||||
sdst = xrealloc((ptr_t)sdst,
|
||||
(size_t)dstsize * sizeof(*sdst));
|
||||
edst = &sdst[dstsize];
|
||||
dst = &edst[-MALLOC_INCR];
|
||||
}
|
||||
}
|
||||
*dst = 0;
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strcpy(Char *dst, const Char *src)
|
||||
{
|
||||
Char *sdst;
|
||||
|
||||
sdst = dst;
|
||||
while ((*dst++ = *src++) != '\0')
|
||||
continue;
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strncpy(Char *dst, const Char *src, size_t n)
|
||||
{
|
||||
Char *sdst;
|
||||
|
||||
if (n == 0)
|
||||
return(dst);
|
||||
|
||||
sdst = dst;
|
||||
do
|
||||
if ((*dst++ = *src++) == '\0') {
|
||||
while (--n != 0)
|
||||
*dst++ = '\0';
|
||||
return(sdst);
|
||||
}
|
||||
while (--n != 0);
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strcat(Char *dst, const Char *src)
|
||||
{
|
||||
short *sdst;
|
||||
|
||||
sdst = dst;
|
||||
while (*dst++)
|
||||
continue;
|
||||
--dst;
|
||||
while ((*dst++ = *src++) != '\0')
|
||||
continue;
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
#ifdef NOTUSED
|
||||
Char *
|
||||
s_strncat(Char *dst, Char *src, size_t n)
|
||||
{
|
||||
Char *sdst;
|
||||
|
||||
if (n == 0)
|
||||
return (dst);
|
||||
|
||||
sdst = dst;
|
||||
|
||||
while (*dst++)
|
||||
continue;
|
||||
--dst;
|
||||
|
||||
do
|
||||
if ((*dst++ = *src++) == '\0')
|
||||
return(sdst);
|
||||
while (--n != 0)
|
||||
continue;
|
||||
|
||||
*dst = '\0';
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Char *
|
||||
s_strchr(const Char *str, int ch)
|
||||
{
|
||||
do
|
||||
if (*str == ch)
|
||||
return __UNCONST(str);
|
||||
while (*str++);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strrchr(const Char *str, int ch)
|
||||
{
|
||||
const Char *rstr;
|
||||
|
||||
rstr = NULL;
|
||||
do
|
||||
if (*str == ch)
|
||||
rstr = str;
|
||||
while (*str++);
|
||||
return __UNCONST(rstr);
|
||||
}
|
||||
|
||||
size_t
|
||||
s_strlen(const Char *str)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
for (n = 0; *str++; n++)
|
||||
continue;
|
||||
return (n);
|
||||
}
|
||||
|
||||
int
|
||||
s_strcmp(const Char *str1, const Char *str2)
|
||||
{
|
||||
for (; *str1 && *str1 == *str2; str1++, str2++)
|
||||
continue;
|
||||
/*
|
||||
* The following case analysis is necessary so that characters which look
|
||||
* negative collate low against normal characters but high against the
|
||||
* end-of-string NUL.
|
||||
*/
|
||||
if (*str1 == '\0' && *str2 == '\0')
|
||||
return (0);
|
||||
else if (*str1 == '\0')
|
||||
return (-1);
|
||||
else if (*str2 == '\0')
|
||||
return (1);
|
||||
else
|
||||
return (*str1 - *str2);
|
||||
}
|
||||
|
||||
int
|
||||
s_strncmp(const Char *str1, const Char *str2, size_t n)
|
||||
{
|
||||
if (n == 0)
|
||||
return (0);
|
||||
do {
|
||||
if (*str1 != *str2) {
|
||||
/*
|
||||
* The following case analysis is necessary so that characters
|
||||
* which look negative collate low against normal characters
|
||||
* but high against the end-of-string NUL.
|
||||
*/
|
||||
if (*str1 == '\0')
|
||||
return (-1);
|
||||
else if (*str2 == '\0')
|
||||
return (1);
|
||||
else
|
||||
return (*str1 - *str2);
|
||||
}
|
||||
if (*str1 == '\0')
|
||||
return(0);
|
||||
str1++, str2++;
|
||||
} while (--n != 0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strsave(const Char *s)
|
||||
{
|
||||
const Char *p;
|
||||
Char *n;
|
||||
|
||||
if (s == 0)
|
||||
s = STRNULL;
|
||||
for (p = s; *p++;)
|
||||
continue;
|
||||
p = n = xmalloc((size_t)(p - s) * sizeof(*n));
|
||||
while ((*n++ = *s++) != '\0')
|
||||
continue;
|
||||
return __UNCONST(p);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strspl(const Char *cp, const Char *dp)
|
||||
{
|
||||
Char *ep, *d;
|
||||
const Char *p, *q;
|
||||
|
||||
if (!cp)
|
||||
cp = STRNULL;
|
||||
if (!dp)
|
||||
dp = STRNULL;
|
||||
for (p = cp; *p++;)
|
||||
continue;
|
||||
for (q = dp; *q++;)
|
||||
continue;
|
||||
ep = xmalloc((size_t)((p - cp) + (q - dp) - 1) * sizeof(*ep));
|
||||
for (d = ep, q = cp; (*d++ = *q++) != '\0';)
|
||||
continue;
|
||||
for (d--, q = dp; (*d++ = *q++) != '\0';)
|
||||
continue;
|
||||
return (ep);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strend(const Char *cp)
|
||||
{
|
||||
if (!cp)
|
||||
return __UNCONST(cp);
|
||||
while (*cp)
|
||||
cp++;
|
||||
return __UNCONST(cp);
|
||||
}
|
||||
|
||||
Char *
|
||||
s_strstr(const Char *s, const Char *t)
|
||||
{
|
||||
do {
|
||||
const Char *ss = s;
|
||||
const Char *tt = t;
|
||||
|
||||
do
|
||||
if (*tt == '\0')
|
||||
return __UNCONST(s);
|
||||
while (*ss++ == *tt++);
|
||||
} while (*s++ != '\0');
|
||||
return (NULL);
|
||||
}
|
||||
#endif /* SHORT_STRINGS */
|
||||
|
||||
char *
|
||||
short2qstr(const Char *src)
|
||||
{
|
||||
static char *sdst = NULL;
|
||||
static size_t dstsize = 0;
|
||||
char *dst, *edst;
|
||||
|
||||
if (src == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (sdst == NULL) {
|
||||
dstsize = MALLOC_INCR;
|
||||
sdst = xmalloc((size_t)dstsize * sizeof(*sdst));
|
||||
}
|
||||
dst = sdst;
|
||||
edst = &dst[dstsize];
|
||||
while (*src) {
|
||||
|
||||
if (*src & QUOTE) {
|
||||
*dst++ = '\\';
|
||||
if (dst == edst) {
|
||||
dstsize += MALLOC_INCR;
|
||||
sdst = xrealloc((ptr_t) sdst,
|
||||
(size_t)dstsize * sizeof(*sdst));
|
||||
edst = &sdst[dstsize];
|
||||
dst = &edst[-MALLOC_INCR];
|
||||
}
|
||||
}
|
||||
*dst++ = (char) *src++;
|
||||
if (dst == edst) {
|
||||
dstsize += MALLOC_INCR;
|
||||
sdst = xrealloc((ptr_t) sdst,
|
||||
(size_t)dstsize * sizeof(*sdst));
|
||||
edst = &sdst[dstsize];
|
||||
dst = &edst[-MALLOC_INCR];
|
||||
}
|
||||
}
|
||||
*dst = 0;
|
||||
return (sdst);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: Should we worry about QUOTE'd chars?
|
||||
*/
|
||||
char *
|
||||
vis_str(const Char *cp)
|
||||
{
|
||||
static char *sdst = NULL;
|
||||
static size_t dstsize = 0;
|
||||
const Char *dp;
|
||||
size_t n;
|
||||
|
||||
if (cp == NULL)
|
||||
return (NULL);
|
||||
|
||||
for (dp = cp; *dp++;)
|
||||
continue;
|
||||
n = ((size_t)(dp - cp) << 2) + 1; /* 4 times + NULL */
|
||||
if (dstsize < n) {
|
||||
sdst = (dstsize ?
|
||||
xrealloc(sdst, (size_t)n * sizeof(*sdst)) :
|
||||
xmalloc((size_t)n * sizeof(*sdst)));
|
||||
dstsize = n;
|
||||
}
|
||||
/*
|
||||
* XXX: When we are in AsciiOnly we want all characters >= 0200 to
|
||||
* be encoded, but currently there is no way in vis to do that.
|
||||
*/
|
||||
(void)strvis(sdst, short2str(cp), VIS_NOSLASH);
|
||||
return (sdst);
|
||||
}
|
||||
285
bin/csh/time.c
Normal file
285
bin/csh/time.c
Normal file
@@ -0,0 +1,285 @@
|
||||
/* $NetBSD: time.c,v 1.20 2013/07/16 17:47:43 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)time.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: time.c,v 1.20 2013/07/16 17:47:43 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef NOT_CSH
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
#include "csh.h"
|
||||
#include "extern.h"
|
||||
#endif
|
||||
#include <util.h>
|
||||
|
||||
/*
|
||||
* C Shell - routines handling process timing and niceing
|
||||
*/
|
||||
static void pdeltat(FILE *, struct timeval *, struct timeval *);
|
||||
static void pcsecs(FILE *, long);
|
||||
|
||||
#ifndef NOT_CSH
|
||||
void
|
||||
settimes(void)
|
||||
{
|
||||
struct rusage ruch;
|
||||
|
||||
(void)clock_gettime(CLOCK_MONOTONIC, &time0);
|
||||
(void)getrusage(RUSAGE_SELF, &ru0);
|
||||
(void)getrusage(RUSAGE_CHILDREN, &ruch);
|
||||
ruadd(&ru0, &ruch);
|
||||
}
|
||||
|
||||
/*
|
||||
* dotime is only called if it is truly a builtin function and not a
|
||||
* prefix to another command
|
||||
*/
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
dotime(Char **v, struct command *t)
|
||||
{
|
||||
struct rusage ru1, ruch;
|
||||
struct timespec timedol;
|
||||
|
||||
(void)getrusage(RUSAGE_SELF, &ru1);
|
||||
(void)getrusage(RUSAGE_CHILDREN, &ruch);
|
||||
ruadd(&ru1, &ruch);
|
||||
(void)clock_gettime(CLOCK_MONOTONIC, &timedol);
|
||||
prusage(cshout, &ru0, &ru1, &timedol, &time0);
|
||||
}
|
||||
|
||||
/*
|
||||
* donice is only called when it on the line by itself or with a +- value
|
||||
*/
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
donice(Char **v, struct command *t)
|
||||
{
|
||||
Char *cp;
|
||||
int nval;
|
||||
|
||||
nval = 0;
|
||||
v++;
|
||||
cp = *v++;
|
||||
if (cp == 0)
|
||||
nval = 4;
|
||||
else if (*v == 0 && any("+-", cp[0]))
|
||||
nval = getn(cp);
|
||||
(void)setpriority(PRIO_PROCESS, 0, nval);
|
||||
}
|
||||
|
||||
void
|
||||
ruadd(struct rusage *ru, struct rusage *ru2)
|
||||
{
|
||||
timeradd(&ru->ru_utime, &ru2->ru_utime, &ru->ru_utime);
|
||||
timeradd(&ru->ru_stime, &ru2->ru_stime, &ru->ru_stime);
|
||||
if (ru2->ru_maxrss > ru->ru_maxrss)
|
||||
ru->ru_maxrss = ru2->ru_maxrss;
|
||||
|
||||
ru->ru_ixrss += ru2->ru_ixrss;
|
||||
ru->ru_idrss += ru2->ru_idrss;
|
||||
ru->ru_isrss += ru2->ru_isrss;
|
||||
ru->ru_minflt += ru2->ru_minflt;
|
||||
ru->ru_majflt += ru2->ru_majflt;
|
||||
ru->ru_nswap += ru2->ru_nswap;
|
||||
ru->ru_inblock += ru2->ru_inblock;
|
||||
ru->ru_oublock += ru2->ru_oublock;
|
||||
ru->ru_msgsnd += ru2->ru_msgsnd;
|
||||
ru->ru_msgrcv += ru2->ru_msgrcv;
|
||||
ru->ru_nsignals += ru2->ru_nsignals;
|
||||
ru->ru_nvcsw += ru2->ru_nvcsw;
|
||||
ru->ru_nivcsw += ru2->ru_nivcsw;
|
||||
}
|
||||
#endif /* NOT_CSH */
|
||||
|
||||
void
|
||||
prusage(FILE *fp, struct rusage *r0, struct rusage *r1, struct timespec *e,
|
||||
struct timespec *b)
|
||||
{
|
||||
#ifndef NOT_CSH
|
||||
struct varent *vp;
|
||||
#endif
|
||||
const char *cp;
|
||||
long i;
|
||||
time_t t;
|
||||
time_t ms;
|
||||
|
||||
cp = "%Uu %Ss %E %P %X+%Dk %I+%Oio %Fpf+%Ww";
|
||||
ms = (e->tv_sec - b->tv_sec) * 100 + (e->tv_nsec - b->tv_nsec) / 10000000;
|
||||
t = (r1->ru_utime.tv_sec - r0->ru_utime.tv_sec) * 100 +
|
||||
(r1->ru_utime.tv_usec - r0->ru_utime.tv_usec) / 10000 +
|
||||
(r1->ru_stime.tv_sec - r0->ru_stime.tv_sec) * 100 +
|
||||
(r1->ru_stime.tv_usec - r0->ru_stime.tv_usec) / 10000;
|
||||
#ifndef NOT_CSH
|
||||
vp = adrof(STRtime);
|
||||
|
||||
if (vp && vp->vec[0] && vp->vec[1])
|
||||
cp = short2str(vp->vec[1]);
|
||||
#endif
|
||||
|
||||
for (; *cp; cp++)
|
||||
if (*cp != '%')
|
||||
(void) fputc(*cp, fp);
|
||||
else if (cp[1])
|
||||
switch (*++cp) {
|
||||
case 'D': /* (average) unshared data size */
|
||||
(void)fprintf(fp, "%ld", t == 0 ? 0L :
|
||||
(long)((r1->ru_idrss + r1->ru_isrss -
|
||||
(r0->ru_idrss + r0->ru_isrss)) / t));
|
||||
break;
|
||||
case 'E': /* elapsed (wall-clock) time */
|
||||
pcsecs(fp, (long) ms);
|
||||
break;
|
||||
case 'F': /* page faults */
|
||||
(void)fprintf(fp, "%ld", r1->ru_majflt - r0->ru_majflt);
|
||||
break;
|
||||
case 'I': /* FS blocks in */
|
||||
(void)fprintf(fp, "%ld", r1->ru_inblock - r0->ru_inblock);
|
||||
break;
|
||||
case 'K': /* (average) total data memory used */
|
||||
(void)fprintf(fp, "%ld", t == 0 ? 0L :
|
||||
(long)(((r1->ru_ixrss + r1->ru_isrss + r1->ru_idrss) -
|
||||
(r0->ru_ixrss + r0->ru_idrss + r0->ru_isrss)) / t));
|
||||
break;
|
||||
case 'M': /* max. Resident Set Size */
|
||||
(void)fprintf(fp, "%ld", r1->ru_maxrss / 2L);
|
||||
break;
|
||||
case 'O': /* FS blocks out */
|
||||
(void)fprintf(fp, "%ld", r1->ru_oublock - r0->ru_oublock);
|
||||
break;
|
||||
case 'P': /* percent time spent running */
|
||||
/* check if it did not run at all */
|
||||
if (ms == 0) {
|
||||
(void)fputs("0.0%", fp);
|
||||
} else {
|
||||
char pb[32];
|
||||
(void)fputs(strpct(pb, sizeof(pb),
|
||||
(uintmax_t)t, (uintmax_t)ms, 1), fp);
|
||||
(void)fputc('%', fp);
|
||||
}
|
||||
break;
|
||||
case 'R': /* page reclaims */
|
||||
(void)fprintf(fp, "%ld", r1->ru_minflt - r0->ru_minflt);
|
||||
break;
|
||||
case 'S': /* system CPU time used */
|
||||
pdeltat(fp, &r1->ru_stime, &r0->ru_stime);
|
||||
break;
|
||||
case 'U': /* user CPU time used */
|
||||
pdeltat(fp, &r1->ru_utime, &r0->ru_utime);
|
||||
break;
|
||||
case 'W': /* number of swaps */
|
||||
i = r1->ru_nswap - r0->ru_nswap;
|
||||
(void)fprintf(fp, "%ld", i);
|
||||
break;
|
||||
case 'X': /* (average) shared text size */
|
||||
(void)fprintf(fp, "%ld", t == 0 ? 0L :
|
||||
(long)((r1->ru_ixrss - r0->ru_ixrss) / t));
|
||||
break;
|
||||
case 'c': /* num. involuntary context switches */
|
||||
(void)fprintf(fp, "%ld", r1->ru_nivcsw - r0->ru_nivcsw);
|
||||
break;
|
||||
case 'k': /* number of signals received */
|
||||
(void)fprintf(fp, "%ld", r1->ru_nsignals-r0->ru_nsignals);
|
||||
break;
|
||||
case 'r': /* socket messages received */
|
||||
(void)fprintf(fp, "%ld", r1->ru_msgrcv - r0->ru_msgrcv);
|
||||
break;
|
||||
case 's': /* socket messages sent */
|
||||
(void)fprintf(fp, "%ld", r1->ru_msgsnd - r0->ru_msgsnd);
|
||||
break;
|
||||
case 'w': /* num. voluntary context switches (waits) */
|
||||
(void)fprintf(fp, "%ld", r1->ru_nvcsw - r0->ru_nvcsw);
|
||||
break;
|
||||
}
|
||||
(void)fputc('\n', fp);
|
||||
}
|
||||
|
||||
static void
|
||||
pdeltat(FILE *fp, struct timeval *t1, struct timeval *t0)
|
||||
{
|
||||
struct timeval td;
|
||||
|
||||
timersub(t1, t0, &td);
|
||||
(void)fprintf(fp, "%ld.%01ld", (long)td.tv_sec,
|
||||
(long)(td.tv_usec / 100000));
|
||||
}
|
||||
|
||||
#define P2DIG(fp, i) (void)fprintf(fp, "%ld%ld", (i) / 10, (i) % 10)
|
||||
|
||||
#ifndef NOT_CSH
|
||||
void
|
||||
psecs(long l)
|
||||
{
|
||||
long i;
|
||||
|
||||
i = l / 3600;
|
||||
if (i) {
|
||||
(void)fprintf(cshout, "%ld:", i);
|
||||
i = l % 3600;
|
||||
P2DIG(cshout, i / 60);
|
||||
goto minsec;
|
||||
}
|
||||
i = l;
|
||||
(void)fprintf(cshout, "%ld", i / 60);
|
||||
minsec:
|
||||
i %= 60;
|
||||
(void)fputc(':', cshout);
|
||||
P2DIG(cshout, i);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
pcsecs(FILE *fp, long l) /* PWP: print mm:ss.dd, l is in sec*100 */
|
||||
{
|
||||
long i;
|
||||
|
||||
i = l / 360000;
|
||||
if (i) {
|
||||
(void)fprintf(fp, "%ld:", i);
|
||||
i = (l % 360000) / 100;
|
||||
P2DIG(fp, i / 60);
|
||||
goto minsec;
|
||||
}
|
||||
i = l / 100;
|
||||
(void)fprintf(fp, "%ld", i / 60);
|
||||
minsec:
|
||||
i %= 60;
|
||||
(void)fputc(':', fp);
|
||||
P2DIG(fp, i);
|
||||
(void)fputc('.', fp);
|
||||
P2DIG(fp, (l % 100));
|
||||
}
|
||||
21
bin/dd/Makefile
Normal file
21
bin/dd/Makefile
Normal file
@@ -0,0 +1,21 @@
|
||||
# $NetBSD: Makefile,v 1.17 2012/08/08 14:09:14 christos Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
RUMPPRG=dd
|
||||
SRCS= args.c conv.c dd.c misc.c position.c
|
||||
|
||||
DPADD+= ${LIBUTIL}
|
||||
LDADD+= -lutil
|
||||
|
||||
.ifdef SMALLPROG
|
||||
CPPFLAGS+= -DNO_CONV -DNO_MSGFMT -DSMALL
|
||||
.else
|
||||
SRCS+= conv_tab.c
|
||||
.ifdef CRUNCHEDPROG
|
||||
CPPFLAGS+= -DSMALL
|
||||
.endif
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
391
bin/dd/args.c
Normal file
391
bin/dd/args.c
Normal file
@@ -0,0 +1,391 @@
|
||||
/* $NetBSD: args.c,v 1.38 2013/07/17 12:55:48 christos 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)args.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: args.c,v 1.38 2013/07/17 12:55:48 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#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 *);
|
||||
|
||||
#ifdef NO_MSGFMT
|
||||
static void f_msgfmt(char *) __dead;
|
||||
#else
|
||||
static void f_msgfmt(char *);
|
||||
#endif /* NO_MSGFMT */
|
||||
|
||||
#ifdef NO_CONV
|
||||
static void f_conv(char *) __dead;
|
||||
#else
|
||||
static void f_conv(char *);
|
||||
static int c_conv(const void *, const void *);
|
||||
#endif /* NO_CONV */
|
||||
|
||||
static void f_bs(char *);
|
||||
static void f_cbs(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_progress(char *);
|
||||
|
||||
static const struct arg {
|
||||
const char *name;
|
||||
void (*f)(char *);
|
||||
u_int set, noset;
|
||||
} args[] = {
|
||||
/* the array needs to be sorted by the first column so
|
||||
bsearch() can be used to find commands quickly */
|
||||
{ "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 },
|
||||
{ "iseek", f_skip, C_SKIP, C_SKIP },
|
||||
{ "msgfmt", f_msgfmt, 0, 0 },
|
||||
{ "obs", f_obs, C_OBS, C_BS|C_OBS },
|
||||
{ "of", f_of, C_OF, C_OF },
|
||||
{ "oseek", f_seek, C_SEEK, C_SEEK },
|
||||
{ "progress", f_progress, 0, 0 },
|
||||
{ "seek", f_seek, C_SEEK, C_SEEK },
|
||||
{ "skip", f_skip, C_SKIP, C_SKIP },
|
||||
};
|
||||
|
||||
/*
|
||||
* args -- parse JCL syntax of dd.
|
||||
*/
|
||||
void
|
||||
jcl(char **argv)
|
||||
{
|
||||
struct arg *ap, tmp;
|
||||
char *oper, *arg;
|
||||
|
||||
in.dbsz = out.dbsz = 512;
|
||||
|
||||
while ((oper = *++argv) != NULL) {
|
||||
if ((oper = strdup(oper)) == NULL) {
|
||||
errx(EXIT_FAILURE,
|
||||
"unable to allocate space for the argument %s",
|
||||
*argv);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if ((arg = strchr(oper, '=')) == NULL) {
|
||||
errx(EXIT_FAILURE, "unknown operand %s", oper);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
*arg++ = '\0';
|
||||
if (!*arg) {
|
||||
errx(EXIT_FAILURE, "no value specified for %s", oper);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
tmp.name = oper;
|
||||
if (!(ap = bsearch(&tmp, args,
|
||||
__arraycount(args), sizeof(*args), c_arg))) {
|
||||
errx(EXIT_FAILURE, "unknown operand %s", tmp.name);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (ddflags & ap->noset) {
|
||||
errx(EXIT_FAILURE,
|
||||
"%s: illegal argument combination or already set",
|
||||
tmp.name);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
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 | C_OSYNC | C_ASCII | C_EBCDIC | C_SPARSE)) {
|
||||
ddflags &= ~C_BS;
|
||||
ddflags |= C_IBS|C_OBS;
|
||||
}
|
||||
|
||||
/* 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(EXIT_FAILURE, "record operations require cbs");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
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(EXIT_FAILURE,
|
||||
"cbs meaningless if not doing record operations");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
} else
|
||||
cfunc = def;
|
||||
|
||||
/* Read, write and seek calls take off_t as arguments.
|
||||
*
|
||||
* The following check is not done because an off_t is a quad
|
||||
* for current NetBSD implementations.
|
||||
*
|
||||
* if (in.offset > INT_MAX/in.dbsz || out.offset > INT_MAX/out.dbsz)
|
||||
* errx(1, "seek offsets cannot be larger than %d", INT_MAX);
|
||||
*/
|
||||
}
|
||||
|
||||
static int
|
||||
c_arg(const void *a, const void *b)
|
||||
{
|
||||
|
||||
return (strcmp(((const struct arg *)a)->name,
|
||||
((const struct arg *)b)->name));
|
||||
}
|
||||
|
||||
static void
|
||||
f_bs(char *arg)
|
||||
{
|
||||
|
||||
in.dbsz = out.dbsz = strsuftoll("block size", arg, 1, UINT_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
f_cbs(char *arg)
|
||||
{
|
||||
|
||||
cbsz = strsuftoll("conversion record size", arg, 1, UINT_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
f_count(char *arg)
|
||||
{
|
||||
|
||||
cpy_cnt = strsuftoll("block count", arg, 0, LLONG_MAX);
|
||||
if (!cpy_cnt)
|
||||
terminate(0);
|
||||
}
|
||||
|
||||
static void
|
||||
f_files(char *arg)
|
||||
{
|
||||
|
||||
files_cnt = (u_int)strsuftoll("file count", arg, 0, UINT_MAX);
|
||||
if (!files_cnt)
|
||||
terminate(0);
|
||||
}
|
||||
|
||||
static void
|
||||
f_ibs(char *arg)
|
||||
{
|
||||
|
||||
if (!(ddflags & C_BS))
|
||||
in.dbsz = strsuftoll("input block size", arg, 1, UINT_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
f_if(char *arg)
|
||||
{
|
||||
|
||||
in.name = arg;
|
||||
}
|
||||
|
||||
#ifdef NO_MSGFMT
|
||||
/* Build a small version (i.e. for a ramdisk root) */
|
||||
static void
|
||||
f_msgfmt(char *arg)
|
||||
{
|
||||
|
||||
errx(EXIT_FAILURE, "msgfmt option disabled");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
#else /* NO_MSGFMT */
|
||||
static void
|
||||
f_msgfmt(char *arg)
|
||||
{
|
||||
|
||||
/*
|
||||
* If the format string is not valid, dd_write_msg() will print
|
||||
* an error and exit.
|
||||
*/
|
||||
dd_write_msg(arg, 0);
|
||||
|
||||
msgfmt = arg;
|
||||
}
|
||||
#endif /* NO_MSGFMT */
|
||||
|
||||
static void
|
||||
f_obs(char *arg)
|
||||
{
|
||||
|
||||
if (!(ddflags & C_BS))
|
||||
out.dbsz = strsuftoll("output block size", arg, 1, UINT_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
f_of(char *arg)
|
||||
{
|
||||
|
||||
out.name = arg;
|
||||
}
|
||||
|
||||
static void
|
||||
f_seek(char *arg)
|
||||
{
|
||||
|
||||
out.offset = strsuftoll("seek blocks", arg, 0, LLONG_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
f_skip(char *arg)
|
||||
{
|
||||
|
||||
in.offset = strsuftoll("skip blocks", arg, 0, LLONG_MAX);
|
||||
}
|
||||
|
||||
static void
|
||||
f_progress(char *arg)
|
||||
{
|
||||
|
||||
progress = strsuftoll("progress blocks", arg, 0, LLONG_MAX);
|
||||
}
|
||||
|
||||
#ifdef NO_CONV
|
||||
/* Build a small version (i.e. for a ramdisk root) */
|
||||
static void
|
||||
f_conv(char *arg)
|
||||
{
|
||||
|
||||
errx(EXIT_FAILURE, "conv option disabled");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
#else /* NO_CONV */
|
||||
|
||||
static const struct conv {
|
||||
const char *name;
|
||||
u_int set, noset;
|
||||
const u_char *ctab;
|
||||
} clist[] = {
|
||||
{ "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 },
|
||||
{ "noerror", C_NOERROR, 0, NULL },
|
||||
{ "notrunc", C_NOTRUNC, 0, NULL },
|
||||
{ "oldascii", C_ASCII, C_EBCDIC, e2a_32V },
|
||||
{ "oldebcdic", C_EBCDIC, C_ASCII, a2e_32V },
|
||||
{ "oldibm", C_EBCDIC, C_ASCII, a2ibm_32V },
|
||||
{ "osync", C_OSYNC, C_BS, NULL },
|
||||
{ "sparse", C_SPARSE, 0, NULL },
|
||||
{ "swab", C_SWAB, 0, NULL },
|
||||
{ "sync", C_SYNC, 0, NULL },
|
||||
{ "ucase", C_UCASE, C_LCASE, NULL },
|
||||
{ "unblock", C_UNBLOCK, C_BLOCK, NULL },
|
||||
/* If you add items to this table, be sure to add the
|
||||
* conversions to the C_BS check in the jcl routine above.
|
||||
*/
|
||||
};
|
||||
|
||||
static void
|
||||
f_conv(char *arg)
|
||||
{
|
||||
struct conv *cp, tmp;
|
||||
|
||||
while (arg != NULL) {
|
||||
tmp.name = strsep(&arg, ",");
|
||||
if (!(cp = bsearch(&tmp, clist,
|
||||
__arraycount(clist), sizeof(*clist), c_conv))) {
|
||||
errx(EXIT_FAILURE, "unknown conversion %s", tmp.name);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (ddflags & cp->noset) {
|
||||
errx(EXIT_FAILURE,
|
||||
"%s: illegal conversion combination", tmp.name);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
ddflags |= cp->set;
|
||||
if (cp->ctab)
|
||||
ctab = cp->ctab;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
c_conv(const void *a, const void *b)
|
||||
{
|
||||
|
||||
return (strcmp(((const struct conv *)a)->name,
|
||||
((const struct conv *)b)->name));
|
||||
}
|
||||
|
||||
#endif /* NO_CONV */
|
||||
283
bin/dd/conv.c
Normal file
283
bin/dd/conv.c
Normal file
@@ -0,0 +1,283 @@
|
||||
/* $NetBSD: conv.c,v 1.17 2003/08/07 09:05:10 agc 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)conv.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: conv.c,v 1.17 2003/08/07 09:05:10 agc Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "dd.h"
|
||||
#include "extern.h"
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
uint64_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 const char no_block[] = "unblock and -DNO_CONV?";
|
||||
void block(void) { errx(EXIT_FAILURE, "%s", no_block + 2); }
|
||||
void block_close(void) { errx(EXIT_FAILURE, "%s", no_block + 2); }
|
||||
void unblock(void) { errx(EXIT_FAILURE, "%s", no_block); }
|
||||
void unblock_close(void) { errx(EXIT_FAILURE, "%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 = 0; /* pacify gcc */
|
||||
uint64_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 = MIN(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)
|
||||
{
|
||||
uint64_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)
|
||||
{
|
||||
uint64_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 */
|
||||
287
bin/dd/conv_tab.c
Normal file
287
bin/dd/conv_tab.c
Normal file
@@ -0,0 +1,287 @@
|
||||
/* $NetBSD: conv_tab.c,v 1.9 2003/08/07 09:05:10 agc 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)conv_tab.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: conv_tab.c,v 1.9 2003/08/07 09:05:10 agc Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/*
|
||||
* There are currently six tables:
|
||||
*
|
||||
* ebcdic -> ascii 32V conv=oldascii
|
||||
* ascii -> ebcdic 32V conv=oldebcdic
|
||||
* ascii -> ibm ebcdic 32V conv=oldibm
|
||||
*
|
||||
* 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. The historic tables were
|
||||
* constructed by running against a file with all possible byte values.
|
||||
*
|
||||
* 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 -- 32V compatible. */
|
||||
const u_char e2a_32V[] = {
|
||||
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, 0133, 0056, 0074, 0050, 0053, 0041, /* 0110 */
|
||||
0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257, /* 0120 */
|
||||
0260, 0261, 0135, 0044, 0052, 0051, 0073, 0136, /* 0130 */
|
||||
0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267, /* 0140 */
|
||||
0270, 0271, 0174, 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, 0313, 0314, 0315, 0316, 0317, 0320, /* 0230 */
|
||||
0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170, /* 0240 */
|
||||
0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327, /* 0250 */
|
||||
0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337, /* 0260 */
|
||||
0340, 0341, 0342, 0343, 0344, 0345, 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 -- 32V compatible. */
|
||||
const u_char a2e_32V[] = {
|
||||
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, 0117, 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, 0112, 0340, 0132, 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, 0152, 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 */
|
||||
};
|
||||
|
||||
/* ASCII to IBM EBCDIC -- 32V compatible. */
|
||||
const u_char a2ibm_32V[] = {
|
||||
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 */
|
||||
};
|
||||
|
||||
/* 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 */
|
||||
};
|
||||
477
bin/dd/dd.1
Normal file
477
bin/dd/dd.1
Normal file
@@ -0,0 +1,477 @@
|
||||
.\" $NetBSD: dd.1,v 1.25 2012/06/20 17:54:16 wiz 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 November 6, 2011
|
||||
.Dt DD 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm dd
|
||||
.Nd convert and copy a file
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op operand ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility copies the standard input to the standard output.
|
||||
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 bs= Ns Ar n
|
||||
Set both input and output block size, 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
|
||||
.Va n
|
||||
bytes.
|
||||
The conversion record size is required by the record oriented conversion
|
||||
values.
|
||||
.It Cm count= Ns Ar n
|
||||
Copy only
|
||||
.Va n
|
||||
input blocks.
|
||||
.It Cm files= Ns Ar n
|
||||
Copy
|
||||
.Va n
|
||||
input files before terminating.
|
||||
This operand is only applicable when the input device is a tape.
|
||||
.It Cm ibs= Ns Ar n
|
||||
Set the input block size to
|
||||
.Va n
|
||||
bytes instead of the default 512.
|
||||
.It Cm if= Ns Ar file
|
||||
Read input from
|
||||
.Ar file
|
||||
instead of the standard input.
|
||||
.It Cm iseek= Ns Ar n
|
||||
Seek on the input file
|
||||
.Ar n
|
||||
blocks.
|
||||
This is synonymous with
|
||||
.Cm skip= Ns Ar n .
|
||||
.It Cm msgfmt= Ns Ar fmt
|
||||
Specify the message format
|
||||
.Ar fmt
|
||||
to be used when writing information to standard output.
|
||||
Possible values are:
|
||||
.Bl -tag -width xxxxx -offset indent -compact
|
||||
.It quiet
|
||||
turns off information summary report except for errors and
|
||||
.Cm progress .
|
||||
.It posix
|
||||
default information summary report as specified by POSIX.
|
||||
.It human
|
||||
default information summary report extended with human-readable
|
||||
values.
|
||||
.El
|
||||
.Pp
|
||||
When
|
||||
.Ar fmt
|
||||
does not correspond to any value given above,
|
||||
it contains a string that will be used as format specifier
|
||||
for the information summary output.
|
||||
Each conversion specification is introduced by the character
|
||||
.Cm % .
|
||||
The following ones are available:
|
||||
.Bl -tag -width xx -offset indent -compact
|
||||
.It b
|
||||
total number of bytes transferred
|
||||
.It B
|
||||
total number of bytes transferred in
|
||||
.Xr humanize_number 3
|
||||
format
|
||||
.It e
|
||||
speed transfer
|
||||
.It E
|
||||
speed transfer in
|
||||
.Xr humanize_number 3
|
||||
format
|
||||
.It i
|
||||
number of partial input block(s)
|
||||
.It I
|
||||
number of full input block(s)
|
||||
.It o
|
||||
number of partial output block(s)
|
||||
.It O
|
||||
number of full output block(s)
|
||||
.It s
|
||||
time elapsed since the beginning in
|
||||
.Do seconds.ms Dc
|
||||
format
|
||||
.It p
|
||||
number of sparse output blocks
|
||||
.It t
|
||||
number of truncated blocks
|
||||
.It w
|
||||
number of odd-length swab blocks
|
||||
.It P
|
||||
singular/plural of
|
||||
.Do block Dc
|
||||
depending on number of sparse blocks
|
||||
.It T
|
||||
singular/plural of
|
||||
.Do block Dc
|
||||
depending on number of truncated blocks
|
||||
.It W
|
||||
singular/plural of
|
||||
.Do block Dc
|
||||
depending on number of swab blocks
|
||||
.El
|
||||
.It Cm obs= Ns Ar n
|
||||
Set the output block size to
|
||||
.Va n
|
||||
bytes instead of the default 512.
|
||||
.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 oseek= Ns Ar n
|
||||
Seek on the output file
|
||||
.Ar n
|
||||
blocks.
|
||||
This is synonymous with
|
||||
.Cm seek= Ns Ar n .
|
||||
.It Cm seek= Ns Ar n
|
||||
Seek
|
||||
.Va 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
|
||||
.Tn NUL
|
||||
bytes.
|
||||
.It Cm skip= Ns Ar n
|
||||
Skip
|
||||
.Va 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 Cm progress= Ns Ar n
|
||||
Switch on display of progress if
|
||||
.Va n
|
||||
is set to any non-zero value.
|
||||
This will cause a
|
||||
.Dq \&.
|
||||
to be printed (to the standard error output) for every
|
||||
.Va n
|
||||
full or partial blocks written to the output file.
|
||||
.Sm off
|
||||
.It Cm conv= Cm value Op \&, Cm value \&...
|
||||
.Sm on
|
||||
Where
|
||||
.Cm value
|
||||
is one of the symbols from the following list.
|
||||
.Bl -tag -width unblock
|
||||
.It Cm ascii , oldascii
|
||||
The same as the
|
||||
.Cm unblock
|
||||
value except that characters are translated from
|
||||
.Tn EBCDIC
|
||||
to
|
||||
.Tn ASCII
|
||||
before the
|
||||
records are converted.
|
||||
(These values imply
|
||||
.Cm unblock
|
||||
if the operand
|
||||
.Cm cbs
|
||||
is also specified.)
|
||||
There are two conversion maps for
|
||||
.Tn ASCII .
|
||||
The value
|
||||
.Cm ascii
|
||||
specifies the recommended one which is compatible with
|
||||
.At V .
|
||||
The value
|
||||
.Cm oldascii
|
||||
specifies the one used in historic
|
||||
.Tn AT\*[Am]T
|
||||
and pre-
|
||||
.Bx 4.3 Reno
|
||||
systems.
|
||||
.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, are reported to the standard
|
||||
error output at the completion of the copy.
|
||||
.It Cm ebcdic , ibm , oldebcdic , oldibm
|
||||
The same as the
|
||||
.Cm block
|
||||
value except that characters are translated from
|
||||
.Tn ASCII
|
||||
to
|
||||
.Tn EBCDIC
|
||||
after the
|
||||
records are converted.
|
||||
(These values imply
|
||||
.Cm block
|
||||
if the operand
|
||||
.Cm cbs
|
||||
is also specified.)
|
||||
There are four conversion maps for
|
||||
.Tn 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.
|
||||
The values
|
||||
.Cm oldebcdic
|
||||
and
|
||||
.Cm oldibm
|
||||
are maps used in historic
|
||||
.Tn AT\*[Am]T
|
||||
and pre
|
||||
.Bx 4.3 Reno
|
||||
systems.
|
||||
.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
|
||||
.Tn 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 .
|
||||
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 sparse
|
||||
If one or more non-final output blocks would consist solely of
|
||||
.Dv NUL
|
||||
bytes, try to seek the output file by the required space instead of
|
||||
filling them with
|
||||
.Dv NUL Ns s .
|
||||
This results in a sparse file on some file systems.
|
||||
.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
|
||||
.Tn 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.
|
||||
Two or more numbers may be separated by an
|
||||
.Dq x
|
||||
to indicate a product.
|
||||
Each number may have one of the following optional suffixes:
|
||||
.Bl -tag -width 3n -offset indent -compact
|
||||
.It b
|
||||
Block; multiply by 512
|
||||
.It k
|
||||
Kibi; multiply by 1024 (1 KiB)
|
||||
.It m
|
||||
Mebi; multiply by 1048576 (1 MiB)
|
||||
.It g
|
||||
Gibi; multiply by 1073741824 (1 GiB)
|
||||
.It t
|
||||
Tebi; multiply by 1099511627776 (1 TiB)
|
||||
.It w
|
||||
Word; multiply by the number of bytes in an integer
|
||||
.El
|
||||
.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
|
||||
signal
|
||||
(see the
|
||||
.Ic status
|
||||
argument for
|
||||
.Xr stty 1 ) ,
|
||||
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
|
||||
The
|
||||
.Nm
|
||||
utility exits 0 on success and \*[Gt]0 if an error occurred.
|
||||
.Sh EXAMPLES
|
||||
To print summary information in human-readable form:
|
||||
.Pp
|
||||
.Dl dd if=/dev/zero of=/dev/null count=1 msgfmt=human
|
||||
.Pp
|
||||
To customize the information summary output and print it through
|
||||
.Xr unvis 3 :
|
||||
.Pp
|
||||
.Bd -literal -offset indent
|
||||
dd if=/dev/zero of=/dev/null count=1 \e
|
||||
msgfmt='speed:%E, in %s seconds\en' 2\*[Gt]\*[Am]1 | unvis
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr cp 1 ,
|
||||
.Xr mt 1 ,
|
||||
.Xr tr 1
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
utility is expected to be a superset of the
|
||||
.St -p1003.2
|
||||
standard.
|
||||
The
|
||||
.Cm files
|
||||
and
|
||||
.Cm msgfmt
|
||||
operands and the
|
||||
.Cm ascii ,
|
||||
.Cm ebcdic ,
|
||||
.Cm ibm ,
|
||||
.Cm oldascii ,
|
||||
.Cm oldebcdic
|
||||
and
|
||||
.Cm oldibm
|
||||
values are extensions to the
|
||||
.Tn POSIX
|
||||
standard.
|
||||
598
bin/dd/dd.c
Normal file
598
bin/dd/dd.c
Normal file
@@ -0,0 +1,598 @@
|
||||
/* $NetBSD: dd.c,v 1.49 2012/02/21 01:49:01 matt 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/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1991, 1993, 1994\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)dd.c 8.5 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: dd.c,v 1.49 2012/02/21 01:49:01 matt Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mtio.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <locale.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 redup_clean_fd(IO *);
|
||||
static void setup(void);
|
||||
|
||||
int main(int, char *[]);
|
||||
|
||||
IO in, out; /* input/output state */
|
||||
STAT st; /* statistics */
|
||||
void (*cfunc)(void); /* conversion function */
|
||||
uint64_t cpy_cnt; /* # of blocks to copy */
|
||||
static off_t pending = 0; /* pending seek if sparse */
|
||||
u_int ddflags; /* conversion options */
|
||||
uint64_t cbsz; /* conversion block size */
|
||||
u_int files_cnt = 1; /* # of files to copy */
|
||||
uint64_t progress = 0; /* display sign of life */
|
||||
const u_char *ctab; /* conversion table */
|
||||
sigset_t infoset; /* a set blocking SIGINFO */
|
||||
const char *msgfmt = "posix"; /* default summary() message format */
|
||||
|
||||
/*
|
||||
* Ops for stdin/stdout and crunch'd dd. These are always host ops.
|
||||
*/
|
||||
static const struct ddfops ddfops_stdfd = {
|
||||
.op_open = open,
|
||||
.op_close = close,
|
||||
.op_fcntl = fcntl,
|
||||
.op_ioctl = ioctl,
|
||||
.op_fstat = fstat,
|
||||
.op_fsync = fsync,
|
||||
.op_ftruncate = ftruncate,
|
||||
.op_lseek = lseek,
|
||||
.op_read = read,
|
||||
.op_write = write,
|
||||
};
|
||||
extern const struct ddfops ddfops_prog;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ch;
|
||||
|
||||
setprogname(argv[0]);
|
||||
(void)setlocale(LC_ALL, "");
|
||||
|
||||
while ((ch = getopt(argc, argv, "")) != -1) {
|
||||
switch (ch) {
|
||||
default:
|
||||
errx(EXIT_FAILURE, "usage: dd [operand ...]");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
argc -= (optind - 1);
|
||||
argv += (optind - 1);
|
||||
|
||||
jcl(argv);
|
||||
#ifndef CRUNCHOPS
|
||||
if (ddfops_prog.op_init && ddfops_prog.op_init() == -1)
|
||||
err(1, "prog init");
|
||||
#endif
|
||||
setup();
|
||||
|
||||
(void)signal(SIGINFO, summaryx);
|
||||
(void)signal(SIGINT, terminate);
|
||||
(void)sigemptyset(&infoset);
|
||||
(void)sigaddset(&infoset, SIGINFO);
|
||||
|
||||
(void)atexit(summary);
|
||||
|
||||
while (files_cnt--)
|
||||
dd_in();
|
||||
|
||||
dd_close();
|
||||
exit(0);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static void
|
||||
setup(void)
|
||||
{
|
||||
#ifdef CRUNCHOPS
|
||||
const struct ddfops *prog_ops = &ddfops_stdfd;
|
||||
#else
|
||||
const struct ddfops *prog_ops = &ddfops_prog;
|
||||
#endif
|
||||
|
||||
if (in.name == NULL) {
|
||||
in.name = "stdin";
|
||||
in.fd = STDIN_FILENO;
|
||||
in.ops = &ddfops_stdfd;
|
||||
} else {
|
||||
in.ops = prog_ops;
|
||||
in.fd = ddop_open(in, in.name, O_RDONLY, 0);
|
||||
if (in.fd < 0)
|
||||
err(EXIT_FAILURE, "%s", in.name);
|
||||
/* NOTREACHED */
|
||||
|
||||
/* Ensure in.fd is outside the stdio descriptor range */
|
||||
redup_clean_fd(&in);
|
||||
}
|
||||
|
||||
getfdtype(&in);
|
||||
|
||||
if (files_cnt > 1 && !(in.flags & ISTAPE)) {
|
||||
errx(EXIT_FAILURE, "files is not supported for non-tape devices");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
if (out.name == NULL) {
|
||||
/* No way to check for read access here. */
|
||||
out.fd = STDOUT_FILENO;
|
||||
out.name = "stdout";
|
||||
out.ops = &ddfops_stdfd;
|
||||
} else {
|
||||
out.ops = prog_ops;
|
||||
#define OFLAGS \
|
||||
(O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC))
|
||||
out.fd = ddop_open(out, 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 = ddop_open(out, out.name, O_WRONLY | OFLAGS,
|
||||
DEFFILEMODE);
|
||||
out.flags |= NOREAD;
|
||||
}
|
||||
if (out.fd < 0) {
|
||||
err(EXIT_FAILURE, "%s", out.name);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* Ensure out.fd is outside the stdio descriptor range */
|
||||
redup_clean_fd(&out);
|
||||
}
|
||||
|
||||
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))) {
|
||||
size_t dbsz = out.dbsz;
|
||||
if (!(ddflags & C_BS))
|
||||
dbsz += in.dbsz - 1;
|
||||
if ((in.db = malloc(dbsz)) == NULL) {
|
||||
err(EXIT_FAILURE, NULL);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
out.db = in.db;
|
||||
} else if ((in.db =
|
||||
malloc((u_int)(MAX(in.dbsz, cbsz) + cbsz))) == NULL ||
|
||||
(out.db = malloc((u_int)(out.dbsz + cbsz))) == NULL) {
|
||||
err(EXIT_FAILURE, NULL);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
in.dbp = in.db;
|
||||
out.dbp = out.db;
|
||||
|
||||
/* Position the input/output streams. */
|
||||
if (in.offset)
|
||||
pos_in();
|
||||
if (out.offset)
|
||||
pos_out();
|
||||
|
||||
/*
|
||||
* 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)ddop_ftruncate(out, out.fd, (off_t)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(EXIT_FAILURE, "case conv and -DNO_CONV");
|
||||
/* NOTREACHED */
|
||||
#else /* NO_CONV */
|
||||
u_int cnt;
|
||||
|
||||
if (ddflags & C_ASCII || ddflags & C_EBCDIC) {
|
||||
if (ddflags & C_LCASE) {
|
||||
for (cnt = 0; cnt < 256; ++cnt)
|
||||
casetab[cnt] = tolower(ctab[cnt]);
|
||||
} else {
|
||||
for (cnt = 0; cnt < 256; ++cnt)
|
||||
casetab[cnt] = toupper(ctab[cnt]);
|
||||
}
|
||||
} else {
|
||||
if (ddflags & C_LCASE) {
|
||||
for (cnt = 0; cnt < 256; ++cnt)
|
||||
casetab[cnt] = tolower(cnt);
|
||||
} else {
|
||||
for (cnt = 0; cnt < 256; ++cnt)
|
||||
casetab[cnt] = toupper(cnt);
|
||||
}
|
||||
}
|
||||
|
||||
ctab = casetab;
|
||||
#endif /* NO_CONV */
|
||||
}
|
||||
|
||||
(void)gettimeofday(&st.start, NULL); /* Statistics timestamp. */
|
||||
}
|
||||
|
||||
static void
|
||||
getfdtype(IO *io)
|
||||
{
|
||||
struct mtget mt;
|
||||
struct stat sb;
|
||||
|
||||
if (io->ops->op_fstat(io->fd, &sb)) {
|
||||
err(EXIT_FAILURE, "%s", io->name);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (S_ISCHR(sb.st_mode))
|
||||
io->flags |= io->ops->op_ioctl(io->fd, MTIOCGET, &mt)
|
||||
? ISCHR : ISTAPE;
|
||||
else if (io->ops->op_lseek(io->fd, (off_t)0, SEEK_CUR) == -1
|
||||
&& errno == ESPIPE)
|
||||
io->flags |= ISPIPE; /* XXX fixed in 4.4BSD */
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the parameter file descriptor to a descriptor that is outside the
|
||||
* stdio descriptor range, if necessary. This is required to avoid
|
||||
* accidentally outputting completion or error messages into the
|
||||
* output file that were intended for the tty.
|
||||
*/
|
||||
static void
|
||||
redup_clean_fd(IO *io)
|
||||
{
|
||||
int fd = io->fd;
|
||||
int newfd;
|
||||
|
||||
if (fd != STDIN_FILENO && fd != STDOUT_FILENO &&
|
||||
fd != STDERR_FILENO)
|
||||
/* File descriptor is ok, return immediately. */
|
||||
return;
|
||||
|
||||
/*
|
||||
* 3 is the first descriptor greater than STD*_FILENO. Any
|
||||
* free descriptor valued 3 or above is acceptable...
|
||||
*/
|
||||
newfd = io->ops->op_fcntl(fd, F_DUPFD, 3);
|
||||
if (newfd < 0) {
|
||||
err(EXIT_FAILURE, "dupfd IO");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
io->ops->op_close(fd);
|
||||
io->fd = newfd;
|
||||
}
|
||||
|
||||
static void
|
||||
dd_in(void)
|
||||
{
|
||||
int flags;
|
||||
int64_t n;
|
||||
|
||||
for (flags = ddflags;;) {
|
||||
if (cpy_cnt && (st.in_full + st.in_part) >= cpy_cnt)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Clear the buffer first if doing "sync" on input.
|
||||
* If doing block operations use spaces. This will
|
||||
* affect not only the C_NOERROR case, but also the
|
||||
* last partial input block which should be padded
|
||||
* with zero and not garbage.
|
||||
*/
|
||||
if (flags & C_SYNC) {
|
||||
if (flags & (C_BLOCK|C_UNBLOCK))
|
||||
(void)memset(in.dbp, ' ', in.dbsz);
|
||||
else
|
||||
(void)memset(in.dbp, 0, in.dbsz);
|
||||
}
|
||||
|
||||
n = ddop_read(in, 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 (!(flags & C_NOERROR)) {
|
||||
err(EXIT_FAILURE, "%s", in.name);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
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)) &&
|
||||
ddop_lseek(in, 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 ((uint64_t)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;
|
||||
}
|
||||
swab(in.dbp, 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.dbsz) {
|
||||
(void)memset(out.dbp, 0, out.dbsz - out.dbcnt);
|
||||
out.dbcnt = out.dbsz;
|
||||
}
|
||||
/* If there are pending sparse blocks, make sure
|
||||
* to write out the final block un-sparse
|
||||
*/
|
||||
if ((out.dbcnt == 0) && pending) {
|
||||
memset(out.db, 0, out.dbsz);
|
||||
out.dbcnt = out.dbsz;
|
||||
out.dbp = out.db + out.dbcnt;
|
||||
pending -= out.dbsz;
|
||||
}
|
||||
if (out.dbcnt)
|
||||
dd_out(1);
|
||||
|
||||
/*
|
||||
* Reporting nfs write error may be deferred until next
|
||||
* write(2) or close(2) system call. So, we need to do an
|
||||
* extra check. If an output is stdout, the file structure
|
||||
* may be shared with other processes and close(2) just
|
||||
* decreases the reference count.
|
||||
*/
|
||||
if (out.fd == STDOUT_FILENO && ddop_fsync(out, out.fd) == -1
|
||||
&& errno != EINVAL) {
|
||||
err(EXIT_FAILURE, "fsync stdout");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (ddop_close(out, out.fd) == -1) {
|
||||
err(EXIT_FAILURE, "close");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dd_out(int force)
|
||||
{
|
||||
static int warned;
|
||||
int64_t cnt, n, 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) {
|
||||
|
||||
if (!force && ddflags & C_SPARSE) {
|
||||
int sparse, i;
|
||||
sparse = 1; /* Is buffer sparse? */
|
||||
for (i = 0; i < cnt; i++)
|
||||
if (outp[i] != 0) {
|
||||
sparse = 0;
|
||||
break;
|
||||
}
|
||||
if (sparse) {
|
||||
pending += cnt;
|
||||
outp += cnt;
|
||||
nw = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pending != 0) {
|
||||
if (ddop_lseek(out,
|
||||
out.fd, pending, SEEK_CUR) == -1)
|
||||
err(EXIT_FAILURE, "%s: seek error creating sparse file",
|
||||
out.name);
|
||||
}
|
||||
nw = bwrite(&out, outp, cnt);
|
||||
if (nw <= 0) {
|
||||
if (nw == 0)
|
||||
errx(EXIT_FAILURE,
|
||||
"%s: end of device", out.name);
|
||||
/* NOTREACHED */
|
||||
if (errno != EINTR)
|
||||
err(EXIT_FAILURE, "%s", out.name);
|
||||
/* NOTREACHED */
|
||||
nw = 0;
|
||||
}
|
||||
if (pending) {
|
||||
st.bytes += pending;
|
||||
st.sparse += pending/out.dbsz;
|
||||
st.out_full += pending/out.dbsz;
|
||||
pending = 0;
|
||||
}
|
||||
outp += nw;
|
||||
st.bytes += nw;
|
||||
if (nw == n) {
|
||||
if ((uint64_t)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(EXIT_FAILURE,
|
||||
"%s: short write on tape device", out.name);
|
||||
/* NOTREACHED */
|
||||
|
||||
}
|
||||
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;
|
||||
|
||||
if (progress && (st.out_full + st.out_part) % progress == 0)
|
||||
(void)write(STDERR_FILENO, ".", 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* A protected against SIGINFO write
|
||||
*/
|
||||
ssize_t
|
||||
bwrite(IO *io, const void *buf, size_t len)
|
||||
{
|
||||
sigset_t oset;
|
||||
ssize_t rv;
|
||||
int oerrno;
|
||||
|
||||
(void)sigprocmask(SIG_BLOCK, &infoset, &oset);
|
||||
rv = io->ops->op_write(io->fd, buf, len);
|
||||
oerrno = errno;
|
||||
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
errno = oerrno;
|
||||
return (rv);
|
||||
}
|
||||
123
bin/dd/dd.h
Normal file
123
bin/dd/dd.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/* $NetBSD: dd.h,v 1.15 2011/02/04 19:42:12 pooka 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
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
struct ddfops {
|
||||
int (*op_init)(void);
|
||||
|
||||
int (*op_open)(const char *, int, ...);
|
||||
int (*op_close)(int);
|
||||
|
||||
int (*op_fcntl)(int, int, ...);
|
||||
int (*op_ioctl)(int, unsigned long, ...);
|
||||
|
||||
int (*op_fstat)(int, struct stat *);
|
||||
int (*op_fsync)(int);
|
||||
int (*op_ftruncate)(int, off_t);
|
||||
|
||||
off_t (*op_lseek)(int, off_t, int);
|
||||
|
||||
ssize_t (*op_read)(int, void *, size_t);
|
||||
ssize_t (*op_write)(int, const void *, size_t);
|
||||
};
|
||||
|
||||
#define ddop_open(dir, a1, a2, ...) dir.ops->op_open(a1, a2, __VA_ARGS__)
|
||||
#define ddop_close(dir, a1) dir.ops->op_close(a1)
|
||||
#define ddop_fcntl(dir, a1, a2, ...) dir.ops->op_fcntl(a1, a2, __VA_ARGS__)
|
||||
#define ddop_ioctl(dir, a1, a2, ...) dir.ops->op_ioctl(a1, a2, __VA_ARGS__)
|
||||
#define ddop_fsync(dir, a1) dir.ops->op_fsync(a1)
|
||||
#define ddop_ftruncate(dir, a1, a2) dir.ops->op_ftruncate(a1, a2)
|
||||
#define ddop_lseek(dir, a1, a2, a3) dir.ops->op_lseek(a1, a2, a3)
|
||||
#define ddop_read(dir, a1, a2, a3) dir.ops->op_read(a1, a2, a3)
|
||||
#define ddop_write(dir, a1, a2, a3) dir.ops->op_write(a1, a2, a3)
|
||||
|
||||
/* Input/output stream state. */
|
||||
typedef struct {
|
||||
u_char *db; /* buffer address */
|
||||
u_char *dbp; /* current buffer I/O address */
|
||||
uint64_t dbcnt; /* current buffer byte count */
|
||||
int64_t dbrcnt; /* last read byte count */
|
||||
uint64_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;
|
||||
|
||||
const char *name; /* name */
|
||||
int fd; /* file descriptor */
|
||||
uint64_t offset; /* # of blocks to skip */
|
||||
struct ddfops const *ops; /* ops to use with fd */
|
||||
} IO;
|
||||
|
||||
typedef struct {
|
||||
uint64_t in_full; /* # of full input blocks */
|
||||
uint64_t in_part; /* # of partial input blocks */
|
||||
uint64_t out_full; /* # of full output blocks */
|
||||
uint64_t out_part; /* # of partial output blocks */
|
||||
uint64_t trunc; /* # of truncated records */
|
||||
uint64_t swab; /* # of odd-length swab blocks */
|
||||
uint64_t sparse; /* # of sparse output blocks */
|
||||
uint64_t bytes; /* # of bytes written */
|
||||
struct timeval start; /* 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_SPARSE 0x200000
|
||||
53
bin/dd/dd_hostops.c
Normal file
53
bin/dd/dd_hostops.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/* $NetBSD: dd_hostops.c,v 1.1 2011/02/04 19:42:12 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||
* 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 NETBSD FOUNDATION, 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 THE FOUNDATION 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/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: dd_hostops.c,v 1.1 2011/02/04 19:42:12 pooka Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "dd.h"
|
||||
|
||||
const struct ddfops ddfops_prog = {
|
||||
.op_open = open,
|
||||
.op_close = close,
|
||||
.op_fcntl = fcntl,
|
||||
.op_ioctl = ioctl,
|
||||
.op_fstat = fstat,
|
||||
.op_fsync = fsync,
|
||||
.op_ftruncate = ftruncate,
|
||||
.op_lseek = lseek,
|
||||
.op_read = read,
|
||||
.op_write = write,
|
||||
};
|
||||
52
bin/dd/dd_rumpops.c
Normal file
52
bin/dd/dd_rumpops.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/* $NetBSD: dd_rumpops.c,v 1.1 2011/02/04 19:42:12 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||
* 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 NETBSD FOUNDATION, 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 THE FOUNDATION 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/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: dd_rumpops.c,v 1.1 2011/02/04 19:42:12 pooka Exp $");
|
||||
#endif /* !lint */
|
||||
|
||||
#include <rump/rump_syscalls.h>
|
||||
#include <rump/rumpclient.h>
|
||||
|
||||
#include "dd.h"
|
||||
|
||||
const struct ddfops ddfops_prog = {
|
||||
.op_init = rumpclient_init,
|
||||
|
||||
.op_open = rump_sys_open,
|
||||
.op_close = rump_sys_close,
|
||||
.op_fcntl = rump_sys_fcntl,
|
||||
.op_ioctl = rump_sys_ioctl,
|
||||
.op_fstat = rump_sys_fstat,
|
||||
.op_fsync = rump_sys_fsync,
|
||||
.op_ftruncate = rump_sys_ftruncate,
|
||||
.op_lseek = rump_sys_lseek,
|
||||
.op_read = rump_sys_read,
|
||||
.op_write = rump_sys_write,
|
||||
};
|
||||
82
bin/dd/extern.h
Normal file
82
bin/dd/extern.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* $NetBSD: extern.h,v 1.22 2011/11/07 22:24:23 jym 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
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#ifdef NO_CONV
|
||||
__dead void block(void);
|
||||
__dead void block_close(void);
|
||||
__dead void unblock(void);
|
||||
__dead void unblock_close(void);
|
||||
#else
|
||||
void block(void);
|
||||
void block_close(void);
|
||||
void unblock(void);
|
||||
void unblock_close(void);
|
||||
#endif
|
||||
|
||||
#ifndef NO_MSGFMT
|
||||
int dd_write_msg(const char *, int);
|
||||
#endif
|
||||
|
||||
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);
|
||||
__dead void terminate(int);
|
||||
void unblock(void);
|
||||
void unblock_close(void);
|
||||
ssize_t bwrite(IO *, const void *, size_t);
|
||||
|
||||
extern IO in, out;
|
||||
extern STAT st;
|
||||
extern void (*cfunc)(void);
|
||||
extern uint64_t cpy_cnt;
|
||||
extern uint64_t cbsz;
|
||||
extern u_int ddflags;
|
||||
extern u_int files_cnt;
|
||||
extern uint64_t progress;
|
||||
extern const u_char *ctab;
|
||||
extern const u_char a2e_32V[], a2e_POSIX[];
|
||||
extern const u_char e2a_32V[], e2a_POSIX[];
|
||||
extern const u_char a2ibm_32V[], a2ibm_POSIX[];
|
||||
extern u_char casetab[];
|
||||
extern const char *msgfmt;
|
||||
342
bin/dd/misc.c
Normal file
342
bin/dd/misc.c
Normal file
@@ -0,0 +1,342 @@
|
||||
/* $NetBSD: misc.c,v 1.23 2011/11/07 22:24:23 jym 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)misc.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: misc.c,v 1.23 2011/11/07 22:24:23 jym Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "dd.h"
|
||||
#include "extern.h"
|
||||
|
||||
#define tv2mS(tv) ((tv).tv_sec * 1000LL + ((tv).tv_usec + 500) / 1000)
|
||||
|
||||
static void posix_summary(void);
|
||||
#ifndef NO_MSGFMT
|
||||
static void custom_summary(void);
|
||||
static void human_summary(void);
|
||||
static void quiet_summary(void);
|
||||
|
||||
static void buffer_write(const char *, size_t, int);
|
||||
#endif /* NO_MSGFMT */
|
||||
|
||||
void
|
||||
summary(void)
|
||||
{
|
||||
|
||||
if (progress)
|
||||
(void)write(STDERR_FILENO, "\n", 1);
|
||||
|
||||
#ifdef NO_MSGFMT
|
||||
return posix_summary();
|
||||
#else /* NO_MSGFMT */
|
||||
if (strncmp(msgfmt, "human", sizeof("human")) == 0)
|
||||
return human_summary();
|
||||
|
||||
if (strncmp(msgfmt, "posix", sizeof("posix")) == 0)
|
||||
return posix_summary();
|
||||
|
||||
if (strncmp(msgfmt, "quiet", sizeof("quiet")) == 0)
|
||||
return quiet_summary();
|
||||
|
||||
return custom_summary();
|
||||
#endif /* NO_MSGFMT */
|
||||
}
|
||||
|
||||
static void
|
||||
posix_summary(void)
|
||||
{
|
||||
char buf[100];
|
||||
int64_t mS;
|
||||
struct timeval tv;
|
||||
|
||||
if (progress)
|
||||
(void)write(STDERR_FILENO, "\n", 1);
|
||||
|
||||
(void)gettimeofday(&tv, NULL);
|
||||
mS = tv2mS(tv) - tv2mS(st.start);
|
||||
if (mS == 0)
|
||||
mS = 1;
|
||||
|
||||
/* Use snprintf(3) so that we don't reenter stdio(3). */
|
||||
(void)snprintf(buf, sizeof(buf),
|
||||
"%llu+%llu records in\n%llu+%llu records out\n",
|
||||
(unsigned long long)st.in_full, (unsigned long long)st.in_part,
|
||||
(unsigned long long)st.out_full, (unsigned long long)st.out_part);
|
||||
(void)write(STDERR_FILENO, buf, strlen(buf));
|
||||
if (st.swab) {
|
||||
(void)snprintf(buf, sizeof(buf), "%llu odd length swab %s\n",
|
||||
(unsigned long long)st.swab,
|
||||
(st.swab == 1) ? "block" : "blocks");
|
||||
(void)write(STDERR_FILENO, buf, strlen(buf));
|
||||
}
|
||||
if (st.trunc) {
|
||||
(void)snprintf(buf, sizeof(buf), "%llu truncated %s\n",
|
||||
(unsigned long long)st.trunc,
|
||||
(st.trunc == 1) ? "block" : "blocks");
|
||||
(void)write(STDERR_FILENO, buf, strlen(buf));
|
||||
}
|
||||
if (st.sparse) {
|
||||
(void)snprintf(buf, sizeof(buf), "%llu sparse output %s\n",
|
||||
(unsigned long long)st.sparse,
|
||||
(st.sparse == 1) ? "block" : "blocks");
|
||||
(void)write(STDERR_FILENO, buf, strlen(buf));
|
||||
}
|
||||
(void)snprintf(buf, sizeof(buf),
|
||||
"%llu bytes transferred in %lu.%03d secs (%llu bytes/sec)\n",
|
||||
(unsigned long long) st.bytes,
|
||||
(long) (mS / 1000),
|
||||
(int) (mS % 1000),
|
||||
(unsigned long long) (st.bytes * 1000LL / mS));
|
||||
(void)write(STDERR_FILENO, buf, strlen(buf));
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
summaryx(int notused)
|
||||
{
|
||||
|
||||
summary();
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
terminate(int signo)
|
||||
{
|
||||
|
||||
summary();
|
||||
(void)raise_default_signal(signo);
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
#ifndef NO_MSGFMT
|
||||
/*
|
||||
* Buffer write(2) calls
|
||||
*/
|
||||
static void
|
||||
buffer_write(const char *str, size_t size, int flush)
|
||||
{
|
||||
static char wbuf[128];
|
||||
static size_t cnt = 0; /* Internal counter to allow wbuf to wrap */
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (str != NULL) {
|
||||
wbuf[cnt++] = str[i];
|
||||
}
|
||||
if (cnt >= sizeof(wbuf)) {
|
||||
(void)write(STDERR_FILENO, wbuf, cnt);
|
||||
cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (flush != 0) {
|
||||
(void)write(STDERR_FILENO, wbuf, cnt);
|
||||
cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write summary to stderr according to format 'fmt'. If 'enable' is 0, it
|
||||
* will not attempt to write anything. Can be used to validate the
|
||||
* correctness of the 'fmt' string.
|
||||
*/
|
||||
int
|
||||
dd_write_msg(const char *fmt, int enable)
|
||||
{
|
||||
char hbuf[7], nbuf[32];
|
||||
const char *ptr;
|
||||
int64_t mS;
|
||||
struct timeval tv;
|
||||
|
||||
(void)gettimeofday(&tv, NULL);
|
||||
mS = tv2mS(tv) - tv2mS(st.start);
|
||||
if (mS == 0)
|
||||
mS = 1;
|
||||
|
||||
#define ADDC(c) do { if (enable != 0) buffer_write(&c, 1, 0); } \
|
||||
while (/*CONSTCOND*/0)
|
||||
#define ADDS(p) do { if (enable != 0) buffer_write(p, strlen(p), 0); } \
|
||||
while (/*CONSTCOND*/0)
|
||||
|
||||
for (ptr = fmt; *ptr; ptr++) {
|
||||
if (*ptr != '%') {
|
||||
ADDC(*ptr);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (*++ptr) {
|
||||
case 'b':
|
||||
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||
(unsigned long long)st.bytes);
|
||||
ADDS(nbuf);
|
||||
break;
|
||||
case 'B':
|
||||
if (humanize_number(hbuf, sizeof(hbuf),
|
||||
st.bytes, "B",
|
||||
HN_AUTOSCALE, HN_DECIMAL) == -1)
|
||||
warnx("humanize_number (bytes transferred)");
|
||||
ADDS(hbuf);
|
||||
break;
|
||||
case 'e':
|
||||
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||
(unsigned long long) (st.bytes * 1000LL / mS));
|
||||
ADDS(nbuf);
|
||||
break;
|
||||
case 'E':
|
||||
if (humanize_number(hbuf, sizeof(hbuf),
|
||||
st.bytes * 1000LL / mS, "B",
|
||||
HN_AUTOSCALE, HN_DECIMAL) == -1)
|
||||
warnx("humanize_number (bytes per second)");
|
||||
ADDS(hbuf); ADDS("/sec");
|
||||
break;
|
||||
case 'i':
|
||||
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||
(unsigned long long)st.in_part);
|
||||
ADDS(nbuf);
|
||||
break;
|
||||
case 'I':
|
||||
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||
(unsigned long long)st.in_full);
|
||||
ADDS(nbuf);
|
||||
break;
|
||||
case 'o':
|
||||
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||
(unsigned long long)st.out_part);
|
||||
ADDS(nbuf);
|
||||
break;
|
||||
case 'O':
|
||||
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||
(unsigned long long)st.out_full);
|
||||
ADDS(nbuf);
|
||||
break;
|
||||
case 's':
|
||||
(void)snprintf(nbuf, sizeof(nbuf), "%li.%03d",
|
||||
(long) (mS / 1000), (int) (mS % 1000));
|
||||
ADDS(nbuf);
|
||||
break;
|
||||
case 'p':
|
||||
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||
(unsigned long long)st.sparse);
|
||||
ADDS(nbuf);
|
||||
break;
|
||||
case 't':
|
||||
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||
(unsigned long long)st.trunc);
|
||||
ADDS(nbuf);
|
||||
break;
|
||||
case 'w':
|
||||
(void)snprintf(nbuf, sizeof(nbuf), "%llu",
|
||||
(unsigned long long)st.swab);
|
||||
ADDS(nbuf);
|
||||
break;
|
||||
case 'P':
|
||||
ADDS("block");
|
||||
if (st.sparse != 1) ADDS("s");
|
||||
break;
|
||||
case 'T':
|
||||
ADDS("block");
|
||||
if (st.trunc != 1) ADDS("s");
|
||||
break;
|
||||
case 'W':
|
||||
ADDS("block");
|
||||
if (st.swab != 1) ADDS("s");
|
||||
break;
|
||||
case '%':
|
||||
ADDC(*ptr);
|
||||
break;
|
||||
default:
|
||||
if (*ptr == '\0')
|
||||
goto done;
|
||||
errx(EXIT_FAILURE, "unknown specifier '%c' in "
|
||||
"msgfmt string", *ptr);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
/* flush buffer */
|
||||
buffer_write(NULL, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
custom_summary(void)
|
||||
{
|
||||
|
||||
dd_write_msg(msgfmt, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
human_summary(void)
|
||||
{
|
||||
(void)dd_write_msg("%I+%i records in\n%O+%o records out\n", 1);
|
||||
if (st.swab) {
|
||||
(void)dd_write_msg("%w odd length swab %W\n", 1);
|
||||
}
|
||||
if (st.trunc) {
|
||||
(void)dd_write_msg("%t truncated %T\n", 1);
|
||||
}
|
||||
if (st.sparse) {
|
||||
(void)dd_write_msg("%p sparse output %P\n", 1);
|
||||
}
|
||||
(void)dd_write_msg("%b bytes (%B) transferred in %s secs "
|
||||
"(%e bytes/sec - %E)\n", 1);
|
||||
}
|
||||
|
||||
static void
|
||||
quiet_summary(void)
|
||||
{
|
||||
|
||||
/* stay quiet */
|
||||
}
|
||||
#endif /* NO_MSGFMT */
|
||||
185
bin/dd/position.c
Normal file
185
bin/dd/position.c
Normal file
@@ -0,0 +1,185 @@
|
||||
/* $NetBSD: position.c,v 1.18 2010/11/22 21:04:28 pooka 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)position.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: position.c,v 1.18 2010/11/22 21:04:28 pooka Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#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 <stdlib.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)
|
||||
{
|
||||
int bcnt, cnt, nr, warned;
|
||||
|
||||
/* If not a pipe or tape device, try to seek on it. */
|
||||
if (!(in.flags & (ISPIPE|ISTAPE))) {
|
||||
if (ddop_lseek(in, in.fd,
|
||||
(off_t)in.offset * (off_t)in.dbsz, SEEK_CUR) == -1) {
|
||||
err(EXIT_FAILURE, "%s", in.name);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
return;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 = ddop_read(in, 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(EXIT_FAILURE, "skip reached end of input");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* 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(EXIT_FAILURE, "%s", in.name);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pos_out(void)
|
||||
{
|
||||
struct mtop t_op;
|
||||
int n;
|
||||
uint64_t cnt;
|
||||
|
||||
/*
|
||||
* 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 (ddop_lseek(out, out.fd,
|
||||
(off_t)out.offset * (off_t)out.dbsz, SEEK_SET) == -1)
|
||||
err(EXIT_FAILURE, "%s", out.name);
|
||||
/* NOTREACHED */
|
||||
return;
|
||||
}
|
||||
|
||||
/* If no read access, try using mtio. */
|
||||
if (out.flags & NOREAD) {
|
||||
t_op.mt_op = MTFSR;
|
||||
t_op.mt_count = out.offset;
|
||||
|
||||
if (ddop_ioctl(out, out.fd, MTIOCTOP, &t_op) < 0)
|
||||
err(EXIT_FAILURE, "%s", out.name);
|
||||
/* NOTREACHED */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read it. */
|
||||
for (cnt = 0; cnt < out.offset; ++cnt) {
|
||||
if ((n = ddop_read(out, out.fd, out.db, out.dbsz)) > 0)
|
||||
continue;
|
||||
|
||||
if (n < 0)
|
||||
err(EXIT_FAILURE, "%s", out.name);
|
||||
/* NOTREACHED */
|
||||
|
||||
/*
|
||||
* 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 (ddop_ioctl(out, out.fd, MTIOCTOP, &t_op) == -1)
|
||||
err(EXIT_FAILURE, "%s", out.name);
|
||||
/* NOTREACHED */
|
||||
|
||||
while (cnt++ < out.offset)
|
||||
if ((uint64_t)(n = bwrite(&out,
|
||||
out.db, out.dbsz)) != out.dbsz)
|
||||
err(EXIT_FAILURE, "%s", out.name);
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
}
|
||||
}
|
||||
6
bin/domainname/Makefile
Normal file
6
bin/domainname/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
# $NetBSD: Makefile,v 1.6 1997/07/20 22:36:50 christos Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
|
||||
PROG= domainname
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
65
bin/domainname/domainname.1
Normal file
65
bin/domainname/domainname.1
Normal file
@@ -0,0 +1,65 @@
|
||||
.\" $NetBSD: domainname.1,v 1.15 2004/06/15 14:08:33 jmmv 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 May 31, 1993
|
||||
.Dt DOMAINNAME 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm domainname
|
||||
.Nd set or print YP domain of current host system
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Ar name-of-domain
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
prints the
|
||||
.Tn YP
|
||||
domain name of the current host.
|
||||
The super-user can set the domain name by supplying an argument;
|
||||
this is usually done in the network initialization script
|
||||
.Pa /etc/rc.d/network ,
|
||||
normally run at boot
|
||||
time.
|
||||
.Sh SEE ALSO
|
||||
.Xr hostname 1 ,
|
||||
.Xr getdomainname 3 ,
|
||||
.Xr setdomainname 3
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility is derived from the
|
||||
.Nm hostname
|
||||
utility, which appeared in
|
||||
.Bx 4.2 .
|
||||
The
|
||||
.Nm
|
||||
utility appeared in
|
||||
.Nx 0.8 .
|
||||
95
bin/domainname/domainname.c
Normal file
95
bin/domainname/domainname.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/* $NetBSD: domainname.c,v 1.15 2011/08/29 14:51:18 joerg 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 <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1988, 1993\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)hostname.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: domainname.c,v 1.15 2011/08/29 14:51:18 joerg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
__dead static void usage(void);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int ch;
|
||||
char domainname[MAXHOSTNAMELEN];
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
while ((ch = getopt(argc, argv, "")) != -1) {
|
||||
switch (ch) {
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr, "usage: %s [name-of-domain]\n", getprogname());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
15
bin/rcmd/Makefile
Normal file
15
bin/rcmd/Makefile
Normal file
@@ -0,0 +1,15 @@
|
||||
# $NetBSD: Makefile,v 1.11 2007/05/28 12:06:17 tls Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
USE_FORT?=yes # setuid
|
||||
# XXX Unsupported Kerberos options were removed from man page
|
||||
# XXX Don't forget to update the man page if you fix Kerberos
|
||||
PROG= rcmd
|
||||
SRCS= rsh.c getport.c
|
||||
CPPFLAGS+=-DIN_RCMD
|
||||
BINOWN= root
|
||||
BINMODE=4555
|
||||
.PATH: ${NETBSDSRCDIR}/usr.bin/rsh
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
199
bin/rcmd/rcmd.1
Normal file
199
bin/rcmd/rcmd.1
Normal file
@@ -0,0 +1,199 @@
|
||||
.\" $NetBSD: rcmd.1,v 1.21 2011/05/31 11:31:10 wiz Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1997 Matthew R. Green.
|
||||
.\" 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" Copyright (c) 1983, 1990 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: @(#)rsh.1 6.10 (Berkeley) 7/24/91
|
||||
.\" from: NetBSD: rsh.1,v 1.3 1997/01/09 20:21:14 tls Exp
|
||||
.\"
|
||||
.Dd May 31, 2011
|
||||
.Dt RCMD 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rcmd
|
||||
.Nd backend driver for
|
||||
.Xr rcmd 3
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl 46dn
|
||||
.Op Fl l Ar username
|
||||
.Op Fl p Ar port
|
||||
.Op Fl u Ar localusername
|
||||
.Ar host
|
||||
.Ar command
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
executes
|
||||
.Ar command
|
||||
on
|
||||
.Ar host .
|
||||
.Pp
|
||||
.Nm
|
||||
copies its standard input to the remote command, the standard
|
||||
output of the remote command to its standard output, and the
|
||||
standard error of the remote command to its standard error.
|
||||
Interrupt, quit and terminate signals are propagated to the remote
|
||||
command;
|
||||
.Nm
|
||||
normally terminates when the remote command does.
|
||||
The options are as follows:
|
||||
.Bl -tag -width flag
|
||||
.It Fl 4
|
||||
Use IPv4 addresses only.
|
||||
.It Fl 6
|
||||
Use IPv6 addresses only.
|
||||
.It Fl d
|
||||
The
|
||||
.Fl d
|
||||
option turns on socket debugging (using
|
||||
.Xr setsockopt 2 )
|
||||
on the
|
||||
.Tn TCP
|
||||
sockets used for communication with the remote host.
|
||||
.It Fl l
|
||||
By default, the remote username is the same as the local username.
|
||||
The
|
||||
.Fl l
|
||||
option allows the remote name to be specified.
|
||||
Another possible way to specify the remote username
|
||||
is the notation
|
||||
.Ar user@host .
|
||||
.It Fl n
|
||||
The
|
||||
.Fl n
|
||||
option redirects input from the special device
|
||||
.Pa /dev/null
|
||||
(see the
|
||||
.Sx BUGS
|
||||
section of this manual page).
|
||||
.It Fl p Ar port
|
||||
Uses the given
|
||||
.Pa port
|
||||
instead of the one assigned to the service
|
||||
.Dq shell .
|
||||
May be given either as symbolic name or as number.
|
||||
.It Fl u
|
||||
The
|
||||
.Fl u
|
||||
option allows the local username to be specified.
|
||||
Only the superuser is allowed to use this option.
|
||||
.El
|
||||
.Pp
|
||||
Shell metacharacters which are not quoted are interpreted on local machine,
|
||||
while quoted metacharacters are interpreted on the remote machine.
|
||||
For example, the command
|
||||
.Pp
|
||||
.Dl rcmd otherhost cat remotefile \*[Gt]\*[Gt] localfile
|
||||
.Pp
|
||||
appends the remote file
|
||||
.Ar remotefile
|
||||
to the local file
|
||||
.Ar localfile ,
|
||||
while
|
||||
.Pp
|
||||
.Dl rcmd otherhost cat remotefile \&"\*[Gt]\*[Gt]\&" other_remotefile
|
||||
.Pp
|
||||
appends
|
||||
.Ar remotefile
|
||||
to
|
||||
.Ar other_remotefile .
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/hosts -compact
|
||||
.It Pa /etc/hosts
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr rsh 1 ,
|
||||
.Xr rcmd 3 ,
|
||||
.Xr environ 7
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Nx 1.3
|
||||
and is primarily derived from
|
||||
.Xr rsh 1 .
|
||||
Its purpose was to create a backend driver for
|
||||
.Xr rcmd 3
|
||||
that would allow the users of
|
||||
.Xr rcmd 3
|
||||
to no longer require super-user privileges.
|
||||
.Sh BUGS
|
||||
If you are using
|
||||
.Xr csh 1
|
||||
and put a
|
||||
.Nm
|
||||
in the background without redirecting its input away from the terminal,
|
||||
it will block even if no reads are posted by the remote command.
|
||||
If no input is desired you should redirect the input of
|
||||
.Nm
|
||||
to
|
||||
.Pa /dev/null
|
||||
using the
|
||||
.Fl n
|
||||
option.
|
||||
.Pp
|
||||
You cannot use
|
||||
.Nm rcmd
|
||||
to run an interactive command (like
|
||||
.Xr rogue 6
|
||||
or
|
||||
.Xr vi 1 ) .
|
||||
Use
|
||||
.Xr rlogin 1
|
||||
instead.
|
||||
.Pp
|
||||
The stop signal,
|
||||
.Dv SIGSTOP ,
|
||||
will stop the local
|
||||
.Nm
|
||||
process only.
|
||||
This is arguably wrong, but currently hard to fix for reasons
|
||||
too complicated to explain here.
|
||||
11
bin/rcp/Makefile
Normal file
11
bin/rcp/Makefile
Normal file
@@ -0,0 +1,11 @@
|
||||
# $NetBSD: Makefile,v 1.25 2009/02/14 08:31:13 lukem Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 7/19/93
|
||||
|
||||
WARNS=3
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
PROG= rcp
|
||||
SRCS= rcp.c util.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,3 +1,5 @@
|
||||
/* $NetBSD: extern.h,v 1.6 2005/03/11 02:55:23 ginsbach Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@@ -10,11 +12,7 @@
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* 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.
|
||||
*
|
||||
@@ -30,42 +28,22 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)random.c 8.1 (Berkeley) 6/10/93
|
||||
* @(#)extern.h 8.1 (Berkeley) 5/31/93
|
||||
*/
|
||||
|
||||
#include "ddb.h"
|
||||
typedef struct {
|
||||
int cnt;
|
||||
char *buf;
|
||||
} BUF;
|
||||
|
||||
static unsigned long randseed = 1;
|
||||
extern int iamremote;
|
||||
|
||||
void
|
||||
srandom(seed)
|
||||
unsigned long seed;
|
||||
{
|
||||
randseed = seed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pseudo-random number generator for randomizing the profiling clock,
|
||||
* and whatever else we might use it for. The result is uniform on
|
||||
* [0, 2^31 - 1].
|
||||
*/
|
||||
unsigned long
|
||||
random()
|
||||
{
|
||||
register long x, hi, lo, t;
|
||||
|
||||
/*
|
||||
* Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1).
|
||||
* From "Random number generators: good ones are hard to find",
|
||||
* Park and Miller, Communications of the ACM, vol. 31, no. 10,
|
||||
* October 1988, p. 1195.
|
||||
*/
|
||||
x = randseed;
|
||||
hi = x / 127773;
|
||||
lo = x % 127773;
|
||||
t = 16807 * lo - 2836 * hi;
|
||||
if (t <= 0)
|
||||
t += 0x7fffffff;
|
||||
randseed = t;
|
||||
return (t);
|
||||
}
|
||||
BUF *allocbuf(BUF *, int, int);
|
||||
char *colon(char *);
|
||||
void lostconn(int);
|
||||
void nospace(void);
|
||||
int okname(char *);
|
||||
void run_err(const char *, ...);
|
||||
int susystem(char *);
|
||||
char *unbracket(char *);
|
||||
void verifydir(char *);
|
||||
42
bin/rcp/pathnames.h
Normal file
42
bin/rcp/pathnames.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/* $NetBSD: pathnames.h,v 1.7 2004/08/19 23:05:00 christos 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.
|
||||
*
|
||||
* @(#)pathnames.h 8.1 (Berkeley) 5/31/93
|
||||
*/
|
||||
|
||||
#include <paths.h>
|
||||
|
||||
#ifdef RESCUEDIR
|
||||
#define _PATH_CP RESCUEDIR "/cp"
|
||||
#define _PATH_RSH RESCUEDIR "/rsh"
|
||||
#else
|
||||
#define _PATH_CP "/bin/cp"
|
||||
#define _PATH_RSH "/usr/bin/rsh"
|
||||
#endif
|
||||
172
bin/rcp/rcp.1
Normal file
172
bin/rcp/rcp.1
Normal file
@@ -0,0 +1,172 @@
|
||||
.\" $NetBSD: rcp.1,v 1.22 2012/03/22 07:58:17 wiz Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1983, 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.
|
||||
.\"
|
||||
.\" @(#)rcp.1 8.1 (Berkeley) 5/31/93
|
||||
.\"
|
||||
.Dd March 8, 2005
|
||||
.Dt RCP 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rcp
|
||||
.Nd remote file copy
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl 46p
|
||||
.Ar file1 file2
|
||||
.Nm
|
||||
.Op Fl 46pr
|
||||
.Ar file ...
|
||||
.Ar directory
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
copies files between machines.
|
||||
Each
|
||||
.Ar file
|
||||
or
|
||||
.Ar directory
|
||||
argument is either a remote file name of the
|
||||
form
|
||||
.Dq rname@rhost:path ,
|
||||
or a local file name (containing no
|
||||
.Sq \&:
|
||||
(colon) characters,
|
||||
or a
|
||||
.Sq /
|
||||
(slash) before any
|
||||
.Sq \&:
|
||||
(colon) characters).
|
||||
.Pp
|
||||
The
|
||||
.Ar rhost
|
||||
can be an IPv4 or an IPv6 address string.
|
||||
Since IPv6 addresses already contain
|
||||
.Sq \&:
|
||||
(colon) characters,
|
||||
an IPv6 address string must be enclosed between
|
||||
.Sq \&[
|
||||
(left square bracket) and
|
||||
.Sq \&]
|
||||
(right square bracket) characters.
|
||||
Otherwise, the first occurrence of a
|
||||
.Sq \&:
|
||||
(colon) character would be
|
||||
interpreted as the separator between the
|
||||
.Ar rhost
|
||||
and the
|
||||
.Ar path .
|
||||
For example,
|
||||
.Pp
|
||||
.Dl [2001:DB8::800:200C:417A]:tmp/file
|
||||
.Pp
|
||||
Options:
|
||||
.Bl -tag -width flag
|
||||
.It Fl 4
|
||||
Use IPv4 addresses only.
|
||||
.It Fl 6
|
||||
Use IPv6 addresses only.
|
||||
.It Fl p
|
||||
The
|
||||
.Fl p
|
||||
option causes
|
||||
.Nm
|
||||
to attempt to preserve (duplicate) in its copies the modification
|
||||
times and modes of the source files, ignoring the
|
||||
.Ar umask .
|
||||
By default, the mode and owner of
|
||||
.Ar file2
|
||||
are preserved if it already existed; otherwise the mode of the source file
|
||||
modified by the
|
||||
.Xr umask 2
|
||||
on the destination host is used.
|
||||
.It Fl r
|
||||
If any of the source files are directories,
|
||||
.Nm
|
||||
copies each subtree rooted at that name; in this case
|
||||
the destination must be a directory.
|
||||
.El
|
||||
.Pp
|
||||
If
|
||||
.Ar path
|
||||
is not a full path name, it is interpreted relative to
|
||||
the login directory of the specified user
|
||||
.Ar ruser
|
||||
on
|
||||
.Ar rhost ,
|
||||
or your current user name if no other remote user name is specified.
|
||||
A
|
||||
.Ar path
|
||||
on a remote host may be quoted (using \e, ", or \(aa)
|
||||
so that the metacharacters are interpreted remotely.
|
||||
.Pp
|
||||
.Nm
|
||||
does not prompt for passwords; it performs remote execution
|
||||
via
|
||||
.Xr rsh 1 ,
|
||||
and requires the same authorization.
|
||||
.Pp
|
||||
.Nm
|
||||
handles third party copies, where neither source nor target files
|
||||
are on the current machine.
|
||||
.Sh SEE ALSO
|
||||
.Xr cp 1 ,
|
||||
.Xr ftp 1 ,
|
||||
.Xr rcmd 1 ,
|
||||
.Xr rlogin 1 ,
|
||||
.Xr rsh 1 ,
|
||||
.Xr rcmd 3 ,
|
||||
.Xr hosts.equiv 5 ,
|
||||
.Xr rhosts 5 ,
|
||||
.Xr environ 7
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility appeared in
|
||||
.Bx 4.2 .
|
||||
The version of
|
||||
.Nm
|
||||
described here
|
||||
has been reimplemented with Kerberos in
|
||||
.Bx 4.3 Reno .
|
||||
.Sh BUGS
|
||||
Doesn't detect all cases where the target of a copy might
|
||||
be a file in cases where only a directory should be legal.
|
||||
.Pp
|
||||
Is confused by any output generated by commands in a
|
||||
.Pa \&.login ,
|
||||
.Pa \&.profile ,
|
||||
or
|
||||
.Pa \&.cshrc
|
||||
file on the remote host.
|
||||
.Pp
|
||||
The destination user and hostname may have to be specified as
|
||||
.Dq rhost.rname
|
||||
when the destination machine is running the
|
||||
.Bx 4.2
|
||||
version of
|
||||
.Nm .
|
||||
813
bin/rcp/rcp.c
Normal file
813
bin/rcp/rcp.c
Normal file
@@ -0,0 +1,813 @@
|
||||
/* $NetBSD: rcp.c,v 1.49 2012/05/07 15:22:54 chs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1990, 1992, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1983, 1990, 1992, 1993\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)rcp.c 8.2 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: rcp.c,v 1.49 2012/05/07 15:22:54 chs Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <locale.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "pathnames.h"
|
||||
#include "extern.h"
|
||||
|
||||
#define OPTIONS "46dfprt"
|
||||
|
||||
struct passwd *pwd;
|
||||
char *pwname;
|
||||
u_short port;
|
||||
uid_t userid;
|
||||
int errs, rem;
|
||||
int pflag, iamremote, iamrecursive, targetshouldbedirectory;
|
||||
int family = AF_UNSPEC;
|
||||
static char dot[] = ".";
|
||||
|
||||
#define CMDNEEDS 64
|
||||
char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */
|
||||
|
||||
int response(void);
|
||||
void rsource(char *, struct stat *);
|
||||
void sink(int, char *[]);
|
||||
void source(int, char *[]);
|
||||
void tolocal(int, char *[]);
|
||||
void toremote(char *, int, char *[]);
|
||||
void usage(void);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct servent *sp;
|
||||
int ch, fflag, tflag;
|
||||
char *targ;
|
||||
const char *shell;
|
||||
|
||||
setprogname(argv[0]);
|
||||
(void)setlocale(LC_ALL, "");
|
||||
|
||||
fflag = tflag = 0;
|
||||
while ((ch = getopt(argc, argv, OPTIONS)) != -1)
|
||||
switch(ch) { /* User-visible flags. */
|
||||
case '4':
|
||||
family = AF_INET;
|
||||
break;
|
||||
case '6':
|
||||
family = AF_INET6;
|
||||
break;
|
||||
case 'K':
|
||||
break;
|
||||
case 'p':
|
||||
pflag = 1;
|
||||
break;
|
||||
case 'r':
|
||||
iamrecursive = 1;
|
||||
break;
|
||||
/* Server options. */
|
||||
case 'd':
|
||||
targetshouldbedirectory = 1;
|
||||
break;
|
||||
case 'f': /* "from" */
|
||||
iamremote = 1;
|
||||
fflag = 1;
|
||||
break;
|
||||
case 't': /* "to" */
|
||||
iamremote = 1;
|
||||
tflag = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
sp = getservbyname(shell = "shell", "tcp");
|
||||
if (sp == NULL)
|
||||
errx(1, "%s/tcp: unknown service", shell);
|
||||
port = sp->s_port;
|
||||
|
||||
if ((pwd = getpwuid(userid = getuid())) == NULL)
|
||||
errx(1, "unknown user %d", (int)userid);
|
||||
|
||||
if ((pwname = strdup(pwd->pw_name)) == NULL)
|
||||
err(1, NULL);
|
||||
|
||||
rem = STDIN_FILENO; /* XXX */
|
||||
|
||||
if (fflag) { /* Follow "protocol", send data. */
|
||||
(void)response();
|
||||
source(argc, argv);
|
||||
exit(errs);
|
||||
}
|
||||
|
||||
if (tflag) { /* Receive data. */
|
||||
sink(argc, argv);
|
||||
exit(errs);
|
||||
}
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
if (argc > 2)
|
||||
targetshouldbedirectory = 1;
|
||||
|
||||
rem = -1;
|
||||
/* Command to be executed on remote system using "rsh". */
|
||||
(void)snprintf(cmd, sizeof(cmd), "rcp%s%s%s",
|
||||
iamrecursive ? " -r" : "", pflag ? " -p" : "",
|
||||
targetshouldbedirectory ? " -d" : "");
|
||||
|
||||
(void)signal(SIGPIPE, lostconn);
|
||||
|
||||
if ((targ = colon(argv[argc - 1])) != NULL)/* Dest is remote host. */
|
||||
toremote(targ, argc, argv);
|
||||
else {
|
||||
tolocal(argc, argv); /* Dest is local host. */
|
||||
if (targetshouldbedirectory)
|
||||
verifydir(argv[argc - 1]);
|
||||
}
|
||||
exit(errs);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
void
|
||||
toremote(char *targ, int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
size_t len;
|
||||
char *bp, *host, *src, *suser, *thost, *tuser;
|
||||
|
||||
*targ++ = 0;
|
||||
if (*targ == 0)
|
||||
targ = dot;
|
||||
|
||||
if ((thost = strchr(argv[argc - 1], '@')) != NULL) {
|
||||
/* user@host */
|
||||
*thost++ = 0;
|
||||
tuser = argv[argc - 1];
|
||||
if (*tuser == '\0')
|
||||
tuser = NULL;
|
||||
else if (!okname(tuser))
|
||||
exit(1);
|
||||
} else {
|
||||
thost = argv[argc - 1];
|
||||
tuser = NULL;
|
||||
}
|
||||
thost = unbracket(thost);
|
||||
|
||||
for (i = 0; i < argc - 1; i++) {
|
||||
src = colon(argv[i]);
|
||||
if (src) { /* remote to remote */
|
||||
*src++ = 0;
|
||||
if (*src == 0)
|
||||
src = dot;
|
||||
host = strchr(argv[i], '@');
|
||||
len = strlen(_PATH_RSH) + strlen(argv[i]) +
|
||||
strlen(src) + (tuser ? strlen(tuser) : 0) +
|
||||
strlen(thost) + strlen(targ) + CMDNEEDS + 20;
|
||||
if (!(bp = malloc(len)))
|
||||
err(1, NULL);
|
||||
if (host) {
|
||||
*host++ = 0;
|
||||
host = unbracket(host);
|
||||
suser = argv[i];
|
||||
if (*suser == '\0')
|
||||
suser = pwname;
|
||||
else if (!okname(suser)) {
|
||||
(void)free(bp);
|
||||
continue;
|
||||
}
|
||||
(void)snprintf(bp, len,
|
||||
"%s %s -l %s -n %s %s '%s%s%s:%s'",
|
||||
_PATH_RSH, host, suser, cmd, src,
|
||||
tuser ? tuser : "", tuser ? "@" : "",
|
||||
thost, targ);
|
||||
} else {
|
||||
host = unbracket(argv[i]);
|
||||
(void)snprintf(bp, len,
|
||||
"exec %s %s -n %s %s '%s%s%s:%s'",
|
||||
_PATH_RSH, argv[i], cmd, src,
|
||||
tuser ? tuser : "", tuser ? "@" : "",
|
||||
thost, targ);
|
||||
}
|
||||
(void)susystem(bp);
|
||||
(void)free(bp);
|
||||
} else { /* local to remote */
|
||||
if (rem == -1) {
|
||||
len = strlen(targ) + CMDNEEDS + 20;
|
||||
if (!(bp = malloc(len)))
|
||||
err(1, NULL);
|
||||
(void)snprintf(bp, len, "%s -t %s", cmd, targ);
|
||||
host = thost;
|
||||
rem = rcmd_af(&host, port, pwname,
|
||||
tuser ? tuser : pwname,
|
||||
bp, NULL, family);
|
||||
if (rem < 0)
|
||||
exit(1);
|
||||
if (response() < 0)
|
||||
exit(1);
|
||||
(void)free(bp);
|
||||
}
|
||||
source(1, argv+i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tolocal(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
size_t len;
|
||||
char *bp, *host, *src, *suser;
|
||||
|
||||
for (i = 0; i < argc - 1; i++) {
|
||||
if (!(src = colon(argv[i]))) { /* Local to local. */
|
||||
len = strlen(_PATH_CP) + strlen(argv[i]) +
|
||||
strlen(argv[argc - 1]) + 20;
|
||||
if (!(bp = malloc(len)))
|
||||
err(1, NULL);
|
||||
(void)snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP,
|
||||
iamrecursive ? " -r" : "", pflag ? " -p" : "",
|
||||
argv[i], argv[argc - 1]);
|
||||
if (susystem(bp))
|
||||
++errs;
|
||||
(void)free(bp);
|
||||
continue;
|
||||
}
|
||||
*src++ = 0;
|
||||
if (*src == 0)
|
||||
src = dot;
|
||||
if ((host = strchr(argv[i], '@')) == NULL) {
|
||||
host = argv[i];
|
||||
suser = pwname;
|
||||
} else {
|
||||
*host++ = 0;
|
||||
suser = argv[i];
|
||||
if (*suser == '\0')
|
||||
suser = pwname;
|
||||
else if (!okname(suser))
|
||||
continue;
|
||||
}
|
||||
host = unbracket(host);
|
||||
len = strlen(src) + CMDNEEDS + 20;
|
||||
if ((bp = malloc(len)) == NULL)
|
||||
err(1, NULL);
|
||||
(void)snprintf(bp, len, "%s -f %s", cmd, src);
|
||||
rem =
|
||||
rcmd_af(&host, port, pwname, suser, bp, NULL, family);
|
||||
(void)free(bp);
|
||||
if (rem < 0) {
|
||||
++errs;
|
||||
continue;
|
||||
}
|
||||
sink(1, argv + argc - 1);
|
||||
(void)close(rem);
|
||||
rem = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
source(int argc, char *argv[])
|
||||
{
|
||||
struct stat stb;
|
||||
static BUF buffer;
|
||||
BUF *bp;
|
||||
off_t i;
|
||||
off_t amt;
|
||||
int fd, haderr, indx, result;
|
||||
char *last, *name, buf[BUFSIZ];
|
||||
|
||||
for (indx = 0; indx < argc; ++indx) {
|
||||
name = argv[indx];
|
||||
if ((fd = open(name, O_RDONLY, 0)) < 0)
|
||||
goto syserr;
|
||||
if (fstat(fd, &stb)) {
|
||||
syserr: run_err("%s: %s", name, strerror(errno));
|
||||
goto next;
|
||||
}
|
||||
switch (stb.st_mode & S_IFMT) {
|
||||
case S_IFREG:
|
||||
break;
|
||||
case S_IFDIR:
|
||||
if (iamrecursive) {
|
||||
rsource(name, &stb);
|
||||
goto next;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
run_err("%s: not a regular file", name);
|
||||
goto next;
|
||||
}
|
||||
if ((last = strrchr(name, '/')) == NULL)
|
||||
last = name;
|
||||
else
|
||||
++last;
|
||||
if (pflag) {
|
||||
/*
|
||||
* Make it compatible with possible future
|
||||
* versions expecting microseconds.
|
||||
*/
|
||||
(void)snprintf(buf, sizeof(buf), "T%lld %ld %lld %ld\n",
|
||||
(long long)stb.st_mtimespec.tv_sec,
|
||||
(long)stb.st_mtimespec.tv_nsec / 1000,
|
||||
(long long)stb.st_atimespec.tv_sec,
|
||||
(long)stb.st_atimespec.tv_nsec / 1000);
|
||||
(void)write(rem, buf, strlen(buf));
|
||||
if (response() < 0)
|
||||
goto next;
|
||||
}
|
||||
#define RCPMODEMASK (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO)
|
||||
(void)snprintf(buf, sizeof(buf), "C%04o %lld %s\n",
|
||||
stb.st_mode & RCPMODEMASK, (long long)stb.st_size, last);
|
||||
(void)write(rem, buf, strlen(buf));
|
||||
if (response() < 0)
|
||||
goto next;
|
||||
if ((bp = allocbuf(&buffer, fd, BUFSIZ)) == NULL) {
|
||||
next: (void)close(fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Keep writing after an error so that we stay sync'd up. */
|
||||
haderr = 0;
|
||||
for (i = 0; i < stb.st_size; i += bp->cnt) {
|
||||
amt = bp->cnt;
|
||||
if (i + amt > stb.st_size)
|
||||
amt = stb.st_size - i;
|
||||
if (!haderr) {
|
||||
result = read(fd, bp->buf, (size_t)amt);
|
||||
if (result != amt)
|
||||
haderr = result >= 0 ? EIO : errno;
|
||||
}
|
||||
if (haderr)
|
||||
(void)write(rem, bp->buf, (size_t)amt);
|
||||
else {
|
||||
result = write(rem, bp->buf, (size_t)amt);
|
||||
if (result != amt)
|
||||
haderr = result >= 0 ? EIO : errno;
|
||||
}
|
||||
}
|
||||
if (close(fd) && !haderr)
|
||||
haderr = errno;
|
||||
if (!haderr)
|
||||
(void)write(rem, "", 1);
|
||||
else
|
||||
run_err("%s: %s", name, strerror(haderr));
|
||||
(void)response();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rsource(char *name, struct stat *statp)
|
||||
{
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
char *last, *vect[1], path[MAXPATHLEN];
|
||||
|
||||
if (!(dirp = opendir(name))) {
|
||||
run_err("%s: %s", name, strerror(errno));
|
||||
return;
|
||||
}
|
||||
last = strrchr(name, '/');
|
||||
if (last == 0)
|
||||
last = name;
|
||||
else
|
||||
last++;
|
||||
if (pflag) {
|
||||
(void)snprintf(path, sizeof(path), "T%lld %ld %lld %ld\n",
|
||||
(long long)statp->st_mtimespec.tv_sec,
|
||||
(long)statp->st_mtimespec.tv_nsec / 1000,
|
||||
(long long)statp->st_atimespec.tv_sec,
|
||||
(long)statp->st_atimespec.tv_nsec / 1000);
|
||||
(void)write(rem, path, strlen(path));
|
||||
if (response() < 0) {
|
||||
(void)closedir(dirp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
(void)snprintf(path, sizeof(path),
|
||||
"D%04o %d %s\n", statp->st_mode & RCPMODEMASK, 0, last);
|
||||
(void)write(rem, path, strlen(path));
|
||||
if (response() < 0) {
|
||||
(void)closedir(dirp);
|
||||
return;
|
||||
}
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
if (dp->d_ino == 0)
|
||||
continue;
|
||||
if (!strcmp(dp->d_name, dot) || !strcmp(dp->d_name, ".."))
|
||||
continue;
|
||||
if (strlen(name) + 1 + strlen(dp->d_name) >= MAXPATHLEN - 1) {
|
||||
run_err("%s/%s: name too long", name, dp->d_name);
|
||||
continue;
|
||||
}
|
||||
(void)snprintf(path, sizeof(path), "%s/%s", name, dp->d_name);
|
||||
vect[0] = path;
|
||||
source(1, vect);
|
||||
}
|
||||
(void)closedir(dirp);
|
||||
(void)write(rem, "E\n", 2);
|
||||
(void)response();
|
||||
}
|
||||
|
||||
void
|
||||
sink(int argc, char *argv[])
|
||||
{
|
||||
static BUF buffer;
|
||||
struct stat stb;
|
||||
struct timeval tv[2];
|
||||
enum { YES, NO, DISPLAYED } wrerr;
|
||||
BUF *bp;
|
||||
ssize_t j;
|
||||
off_t i;
|
||||
off_t amt;
|
||||
off_t count;
|
||||
int exists, first, ofd;
|
||||
mode_t mask;
|
||||
mode_t mode;
|
||||
mode_t omode;
|
||||
int setimes, targisdir;
|
||||
int wrerrno = 0; /* pacify gcc */
|
||||
char ch, *cp, *np, *targ, *vect[1], buf[BUFSIZ];
|
||||
const char *why;
|
||||
off_t size;
|
||||
char *namebuf = NULL;
|
||||
size_t cursize = 0;
|
||||
|
||||
#define atime tv[0]
|
||||
#define mtime tv[1]
|
||||
#define SCREWUP(str) { why = str; goto screwup; }
|
||||
|
||||
setimes = targisdir = 0;
|
||||
mask = umask(0);
|
||||
if (!pflag)
|
||||
(void)umask(mask);
|
||||
if (argc != 1) {
|
||||
run_err("ambiguous target");
|
||||
exit(1);
|
||||
}
|
||||
targ = *argv;
|
||||
if (targetshouldbedirectory)
|
||||
verifydir(targ);
|
||||
(void)write(rem, "", 1);
|
||||
if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))
|
||||
targisdir = 1;
|
||||
for (first = 1;; first = 0) {
|
||||
cp = buf;
|
||||
if (read(rem, cp, 1) <= 0)
|
||||
goto out;
|
||||
if (*cp++ == '\n')
|
||||
SCREWUP("unexpected <newline>");
|
||||
do {
|
||||
if (read(rem, &ch, sizeof(ch)) != sizeof(ch))
|
||||
SCREWUP("lost connection");
|
||||
*cp++ = ch;
|
||||
} while (cp < &buf[BUFSIZ - 1] && ch != '\n');
|
||||
*cp = 0;
|
||||
|
||||
if (buf[0] == '\01' || buf[0] == '\02') {
|
||||
if (iamremote == 0)
|
||||
(void)write(STDERR_FILENO,
|
||||
buf + 1, strlen(buf + 1));
|
||||
if (buf[0] == '\02')
|
||||
exit(1);
|
||||
++errs;
|
||||
continue;
|
||||
}
|
||||
if (buf[0] == 'E') {
|
||||
(void)write(rem, "", 1);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ch == '\n')
|
||||
*--cp = 0;
|
||||
|
||||
#define getnum(t) (t) = 0; while (isdigit((unsigned char)*cp)) (t) = (t) * 10 + (*cp++ - '0');
|
||||
cp = buf;
|
||||
if (*cp == 'T') {
|
||||
setimes++;
|
||||
cp++;
|
||||
getnum(mtime.tv_sec);
|
||||
if (*cp++ != ' ')
|
||||
SCREWUP("mtime.sec not delimited");
|
||||
getnum(mtime.tv_usec);
|
||||
if (*cp++ != ' ')
|
||||
SCREWUP("mtime.usec not delimited");
|
||||
getnum(atime.tv_sec);
|
||||
if (*cp++ != ' ')
|
||||
SCREWUP("atime.sec not delimited");
|
||||
getnum(atime.tv_usec);
|
||||
if (*cp++ != '\0')
|
||||
SCREWUP("atime.usec not delimited");
|
||||
(void)write(rem, "", 1);
|
||||
continue;
|
||||
}
|
||||
if (*cp != 'C' && *cp != 'D') {
|
||||
/*
|
||||
* Check for the case "rcp remote:foo\* local:bar".
|
||||
* In this case, the line "No match." can be returned
|
||||
* by the shell before the rcp command on the remote is
|
||||
* executed so the ^Aerror_message convention isn't
|
||||
* followed.
|
||||
*/
|
||||
if (first) {
|
||||
run_err("%s", cp);
|
||||
exit(1);
|
||||
}
|
||||
SCREWUP("expected control record");
|
||||
}
|
||||
mode = 0;
|
||||
for (++cp; cp < buf + 5; cp++) {
|
||||
if (*cp < '0' || *cp > '7')
|
||||
SCREWUP("bad mode");
|
||||
mode = (mode << 3) | (*cp - '0');
|
||||
}
|
||||
if (*cp++ != ' ')
|
||||
SCREWUP("mode not delimited");
|
||||
|
||||
for (size = 0; isdigit((unsigned char)*cp);)
|
||||
size = size * 10 + (*cp++ - '0');
|
||||
if (*cp++ != ' ')
|
||||
SCREWUP("size not delimited");
|
||||
if (targisdir) {
|
||||
char *newnamebuf;
|
||||
size_t need;
|
||||
|
||||
need = strlen(targ) + strlen(cp) + 2;
|
||||
if (need > cursize) {
|
||||
need += 256;
|
||||
newnamebuf = realloc(namebuf, need);
|
||||
if (newnamebuf != NULL) {
|
||||
namebuf = newnamebuf;
|
||||
cursize = need;
|
||||
} else {
|
||||
run_err("%s", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
(void)snprintf(namebuf, cursize, "%s%s%s", targ,
|
||||
*targ ? "/" : "", cp);
|
||||
np = namebuf;
|
||||
} else
|
||||
np = targ;
|
||||
exists = stat(np, &stb) == 0;
|
||||
if (buf[0] == 'D') {
|
||||
int mod_flag = pflag;
|
||||
if (exists) {
|
||||
if (!S_ISDIR(stb.st_mode)) {
|
||||
errno = ENOTDIR;
|
||||
goto bad;
|
||||
}
|
||||
if (pflag)
|
||||
(void)chmod(np, mode);
|
||||
} else {
|
||||
/* Handle copying from a read-only directory */
|
||||
mod_flag = 1;
|
||||
if (mkdir(np, mode | S_IRWXU) < 0)
|
||||
goto bad;
|
||||
}
|
||||
vect[0] = np;
|
||||
sink(1, vect);
|
||||
if (setimes) {
|
||||
setimes = 0;
|
||||
if (utimes(np, tv) < 0)
|
||||
run_err("%s: set times: %s",
|
||||
np, strerror(errno));
|
||||
}
|
||||
if (mod_flag)
|
||||
(void)chmod(np, mode);
|
||||
continue;
|
||||
}
|
||||
omode = mode;
|
||||
mode |= S_IWRITE;
|
||||
if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) {
|
||||
bad: run_err("%s: %s", np, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
(void)write(rem, "", 1);
|
||||
if ((bp = allocbuf(&buffer, ofd, BUFSIZ)) == NULL) {
|
||||
(void)close(ofd);
|
||||
continue;
|
||||
}
|
||||
cp = bp->buf;
|
||||
wrerr = NO;
|
||||
count = 0;
|
||||
for (i = 0; i < size; i += BUFSIZ) {
|
||||
amt = BUFSIZ;
|
||||
if (i + amt > size)
|
||||
amt = size - i;
|
||||
count += amt;
|
||||
do {
|
||||
j = read(rem, cp, (size_t)amt);
|
||||
if (j == -1) {
|
||||
run_err("%s", j ? strerror(errno) :
|
||||
"dropped connection");
|
||||
exit(1);
|
||||
}
|
||||
amt -= j;
|
||||
cp += j;
|
||||
} while (amt > 0);
|
||||
if (count == bp->cnt) {
|
||||
/* Keep reading so we stay sync'd up. */
|
||||
if (wrerr == NO) {
|
||||
j = write(ofd, bp->buf, (size_t)count);
|
||||
if (j != count) {
|
||||
wrerr = YES;
|
||||
wrerrno = j >= 0 ? EIO : errno;
|
||||
}
|
||||
}
|
||||
count = 0;
|
||||
cp = bp->buf;
|
||||
}
|
||||
}
|
||||
if (count != 0 && wrerr == NO &&
|
||||
(j = write(ofd, bp->buf, (size_t)count)) != count) {
|
||||
wrerr = YES;
|
||||
wrerrno = j >= 0 ? EIO : errno;
|
||||
}
|
||||
if (ftruncate(ofd, size)) {
|
||||
run_err("%s: truncate: %s", np, strerror(errno));
|
||||
wrerr = DISPLAYED;
|
||||
}
|
||||
if (pflag) {
|
||||
if (exists || omode != mode)
|
||||
if (fchmod(ofd, omode))
|
||||
run_err("%s: set mode: %s",
|
||||
np, strerror(errno));
|
||||
} else {
|
||||
if (!exists && omode != mode)
|
||||
if (fchmod(ofd, omode & ~mask))
|
||||
run_err("%s: set mode: %s",
|
||||
np, strerror(errno));
|
||||
}
|
||||
#ifndef __SVR4
|
||||
if (setimes && wrerr == NO) {
|
||||
setimes = 0;
|
||||
if (futimes(ofd, tv) < 0) {
|
||||
run_err("%s: set times: %s",
|
||||
np, strerror(errno));
|
||||
wrerr = DISPLAYED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
(void)close(ofd);
|
||||
#ifdef __SVR4
|
||||
if (setimes && wrerr == NO) {
|
||||
setimes = 0;
|
||||
if (utimes(np, tv) < 0) {
|
||||
run_err("%s: set times: %s",
|
||||
np, strerror(errno));
|
||||
wrerr = DISPLAYED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
(void)response();
|
||||
switch(wrerr) {
|
||||
case YES:
|
||||
run_err("%s: write: %s", np, strerror(wrerrno));
|
||||
break;
|
||||
case NO:
|
||||
(void)write(rem, "", 1);
|
||||
break;
|
||||
case DISPLAYED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (namebuf) {
|
||||
free(namebuf);
|
||||
}
|
||||
return;
|
||||
|
||||
screwup:
|
||||
run_err("protocol error: %s", why);
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
response(void)
|
||||
{
|
||||
char ch, *cp, resp, rbuf[BUFSIZ];
|
||||
|
||||
if (read(rem, &resp, sizeof(resp)) != sizeof(resp))
|
||||
lostconn(0);
|
||||
|
||||
cp = rbuf;
|
||||
switch(resp) {
|
||||
case 0: /* ok */
|
||||
return (0);
|
||||
default:
|
||||
*cp++ = resp;
|
||||
/* FALLTHROUGH */
|
||||
case 1: /* error, followed by error msg */
|
||||
case 2: /* fatal error, "" */
|
||||
do {
|
||||
if (read(rem, &ch, sizeof(ch)) != sizeof(ch))
|
||||
lostconn(0);
|
||||
*cp++ = ch;
|
||||
} while (cp < &rbuf[BUFSIZ] && ch != '\n');
|
||||
|
||||
if (!iamremote)
|
||||
(void)write(STDERR_FILENO, rbuf, (size_t)(cp - rbuf));
|
||||
++errs;
|
||||
if (resp == 1)
|
||||
return (-1);
|
||||
exit(1);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: rcp [-46p] f1 f2; or: rcp [-46pr] f1 ... fn directory\n");
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
void
|
||||
run_err(const char *fmt, ...)
|
||||
{
|
||||
static FILE *fp;
|
||||
va_list ap;
|
||||
|
||||
++errs;
|
||||
if (fp == NULL && !(fp = fdopen(rem, "w")))
|
||||
return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
(void)fprintf(fp, "%c", 0x01);
|
||||
(void)fprintf(fp, "rcp: ");
|
||||
(void)vfprintf(fp, fmt, ap);
|
||||
(void)fprintf(fp, "\n");
|
||||
(void)fflush(fp);
|
||||
va_end(ap);
|
||||
|
||||
if (!iamremote) {
|
||||
va_start(ap, fmt);
|
||||
vwarnx(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
184
bin/rcp/util.c
Normal file
184
bin/rcp/util.c
Normal file
@@ -0,0 +1,184 @@
|
||||
/* $NetBSD: util.c,v 1.11 2006/12/15 22:45:34 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 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/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)util.c 8.2 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: util.c,v 1.11 2006/12/15 22:45:34 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <paths.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
char *
|
||||
colon(char *cp)
|
||||
{
|
||||
if (*cp == ':') /* Leading colon is part of file name. */
|
||||
return (0);
|
||||
|
||||
for (; *cp; ++cp) {
|
||||
if (*cp == ':')
|
||||
return (cp);
|
||||
if (*cp == '/')
|
||||
return (0);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
char *
|
||||
unbracket(char *cp)
|
||||
{
|
||||
char *ep;
|
||||
|
||||
if (*cp == '[') {
|
||||
ep = cp + (strlen(cp) - 1);
|
||||
if (*ep == ']') {
|
||||
*ep = '\0';
|
||||
++cp;
|
||||
}
|
||||
}
|
||||
return (cp);
|
||||
}
|
||||
|
||||
void
|
||||
verifydir(char *cp)
|
||||
{
|
||||
struct stat stb;
|
||||
|
||||
if (!stat(cp, &stb)) {
|
||||
if (S_ISDIR(stb.st_mode))
|
||||
return;
|
||||
errno = ENOTDIR;
|
||||
}
|
||||
run_err("%s: %s", cp, strerror(errno));
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
int
|
||||
okname(char *cp0)
|
||||
{
|
||||
int c;
|
||||
char *cp;
|
||||
|
||||
cp = cp0;
|
||||
do {
|
||||
c = *cp;
|
||||
if (c & 0200)
|
||||
goto bad;
|
||||
if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-')
|
||||
goto bad;
|
||||
} while (*++cp);
|
||||
return (1);
|
||||
|
||||
bad: warnx("%s: invalid user name", cp0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
susystem(char *s)
|
||||
{
|
||||
sig_t istat, qstat;
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
pid = vfork();
|
||||
switch (pid) {
|
||||
case -1:
|
||||
return (127);
|
||||
|
||||
case 0:
|
||||
(void)execl(_PATH_BSHELL, "sh", "-c", s, NULL);
|
||||
_exit(127);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
istat = signal(SIGINT, SIG_IGN);
|
||||
qstat = signal(SIGQUIT, SIG_IGN);
|
||||
if (waitpid(pid, &status, 0) < 0)
|
||||
status = -1;
|
||||
(void)signal(SIGINT, istat);
|
||||
(void)signal(SIGQUIT, qstat);
|
||||
return (status);
|
||||
}
|
||||
|
||||
BUF *
|
||||
allocbuf(BUF *bp, int fd, int blksize)
|
||||
{
|
||||
struct stat stb;
|
||||
size_t size;
|
||||
char *nbuf;
|
||||
|
||||
if (fstat(fd, &stb) < 0) {
|
||||
run_err("fstat: %s", strerror(errno));
|
||||
return (0);
|
||||
}
|
||||
size = roundup(stb.st_blksize, blksize);
|
||||
if (size == 0)
|
||||
size = blksize;
|
||||
if (bp->cnt >= size)
|
||||
return (bp);
|
||||
if ((nbuf = realloc(bp->buf, size)) == NULL) {
|
||||
free(bp->buf);
|
||||
bp->buf = NULL;
|
||||
bp->cnt = 0;
|
||||
run_err("%s", strerror(errno));
|
||||
return (0);
|
||||
}
|
||||
bp->buf = nbuf;
|
||||
bp->cnt = size;
|
||||
return (bp);
|
||||
}
|
||||
|
||||
void
|
||||
/*ARGSUSED*/
|
||||
lostconn(int signo __unused)
|
||||
{
|
||||
if (!iamremote)
|
||||
warnx("lost connection");
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
COMMON_DIR:=${.PARSEDIR}
|
||||
.if defined(__MINIX)
|
||||
COMMON_CODEDIRS=atomic gen inet md net quad stdlib string
|
||||
COMMON_CODEDIRS=atomic gen inet md net stdlib string
|
||||
.else
|
||||
COMMON_CODEDIRS=atomic gen gmon inet md net quad stdlib string sys
|
||||
.endif
|
||||
|
||||
@@ -1,381 +0,0 @@
|
||||
/* $NetBSD: divide.S,v 1.4 2013/08/19 03:47:06 matt Exp $ */
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __ARM_ARCH_EXT_IDIV__
|
||||
|
||||
#include <machine/asm.h>
|
||||
|
||||
/*
|
||||
* stack is aligned as there's a possibility of branching to .L_overflow
|
||||
* which makes a C call
|
||||
*/
|
||||
|
||||
_ARM_ENTRY(__udivide) /* r0 = r0 / r1; r1 = r0 % r1 */
|
||||
eor r0, r1, r0
|
||||
eor r1, r0, r1
|
||||
eor r0, r1, r0
|
||||
/* r0 = r1 / r0; r1 = r1 % r0 */
|
||||
cmp r0, #1
|
||||
bcc .L_overflow
|
||||
beq .L_divide_l0
|
||||
mov ip, #0
|
||||
movs r1, r1
|
||||
bpl .L_divide_l1
|
||||
orr ip, ip, #0x20000000 /* ip bit 0x20000000 = -ve r1 */
|
||||
movs r1, r1, lsr #1
|
||||
orrcs ip, ip, #0x10000000 /* ip bit 0x10000000 = bit 0 of r1 */
|
||||
b .L_divide_l1
|
||||
|
||||
.L_divide_l0: /* r0 == 1 */
|
||||
mov r0, r1
|
||||
mov r1, #0
|
||||
RET
|
||||
END(__udivide)
|
||||
|
||||
_ARM_ENTRY(__divide) /* r0 = r0 / r1; r1 = r0 % r1 */
|
||||
eor r0, r1, r0
|
||||
eor r1, r0, r1
|
||||
eor r0, r1, r0
|
||||
/* r0 = r1 / r0; r1 = r1 % r0 */
|
||||
cmp r0, #1
|
||||
bcc .L_overflow
|
||||
beq .L_divide_l0
|
||||
ands ip, r0, #0x80000000
|
||||
rsbmi r0, r0, #0
|
||||
ands r2, r1, #0x80000000
|
||||
eor ip, ip, r2
|
||||
rsbmi r1, r1, #0
|
||||
orr ip, r2, ip, lsr #1 /* ip bit 0x40000000 = -ve division */
|
||||
/* ip bit 0x80000000 = -ve remainder */
|
||||
|
||||
.L_divide_l1:
|
||||
mov r2, #1
|
||||
mov r3, #0
|
||||
|
||||
/*
|
||||
* If the highest bit of the dividend is set, we have to be
|
||||
* careful when shifting the divisor. Test this.
|
||||
*/
|
||||
movs r1,r1
|
||||
bpl .L_old_code
|
||||
|
||||
/*
|
||||
* At this point, the highest bit of r1 is known to be set.
|
||||
* We abuse this below in the tst instructions.
|
||||
*/
|
||||
tst r1, r0 /*, lsl #0 */
|
||||
bmi .L_divide_b1
|
||||
tst r1, r0, lsl #1
|
||||
bmi .L_divide_b2
|
||||
tst r1, r0, lsl #2
|
||||
bmi .L_divide_b3
|
||||
tst r1, r0, lsl #3
|
||||
bmi .L_divide_b4
|
||||
tst r1, r0, lsl #4
|
||||
bmi .L_divide_b5
|
||||
tst r1, r0, lsl #5
|
||||
bmi .L_divide_b6
|
||||
tst r1, r0, lsl #6
|
||||
bmi .L_divide_b7
|
||||
tst r1, r0, lsl #7
|
||||
bmi .L_divide_b8
|
||||
tst r1, r0, lsl #8
|
||||
bmi .L_divide_b9
|
||||
tst r1, r0, lsl #9
|
||||
bmi .L_divide_b10
|
||||
tst r1, r0, lsl #10
|
||||
bmi .L_divide_b11
|
||||
tst r1, r0, lsl #11
|
||||
bmi .L_divide_b12
|
||||
tst r1, r0, lsl #12
|
||||
bmi .L_divide_b13
|
||||
tst r1, r0, lsl #13
|
||||
bmi .L_divide_b14
|
||||
tst r1, r0, lsl #14
|
||||
bmi .L_divide_b15
|
||||
tst r1, r0, lsl #15
|
||||
bmi .L_divide_b16
|
||||
tst r1, r0, lsl #16
|
||||
bmi .L_divide_b17
|
||||
tst r1, r0, lsl #17
|
||||
bmi .L_divide_b18
|
||||
tst r1, r0, lsl #18
|
||||
bmi .L_divide_b19
|
||||
tst r1, r0, lsl #19
|
||||
bmi .L_divide_b20
|
||||
tst r1, r0, lsl #20
|
||||
bmi .L_divide_b21
|
||||
tst r1, r0, lsl #21
|
||||
bmi .L_divide_b22
|
||||
tst r1, r0, lsl #22
|
||||
bmi .L_divide_b23
|
||||
tst r1, r0, lsl #23
|
||||
bmi .L_divide_b24
|
||||
tst r1, r0, lsl #24
|
||||
bmi .L_divide_b25
|
||||
tst r1, r0, lsl #25
|
||||
bmi .L_divide_b26
|
||||
tst r1, r0, lsl #26
|
||||
bmi .L_divide_b27
|
||||
tst r1, r0, lsl #27
|
||||
bmi .L_divide_b28
|
||||
tst r1, r0, lsl #28
|
||||
bmi .L_divide_b29
|
||||
tst r1, r0, lsl #29
|
||||
bmi .L_divide_b30
|
||||
tst r1, r0, lsl #30
|
||||
bmi .L_divide_b31
|
||||
/*
|
||||
* instead of:
|
||||
* tst r1, r0, lsl #31
|
||||
* bmi .L_divide_b32
|
||||
*/
|
||||
b .L_divide_b32
|
||||
|
||||
.L_old_code:
|
||||
cmp r1, r0
|
||||
bcc .L_divide_b0
|
||||
cmp r1, r0, lsl #1
|
||||
bcc .L_divide_b1
|
||||
cmp r1, r0, lsl #2
|
||||
bcc .L_divide_b2
|
||||
cmp r1, r0, lsl #3
|
||||
bcc .L_divide_b3
|
||||
cmp r1, r0, lsl #4
|
||||
bcc .L_divide_b4
|
||||
cmp r1, r0, lsl #5
|
||||
bcc .L_divide_b5
|
||||
cmp r1, r0, lsl #6
|
||||
bcc .L_divide_b6
|
||||
cmp r1, r0, lsl #7
|
||||
bcc .L_divide_b7
|
||||
cmp r1, r0, lsl #8
|
||||
bcc .L_divide_b8
|
||||
cmp r1, r0, lsl #9
|
||||
bcc .L_divide_b9
|
||||
cmp r1, r0, lsl #10
|
||||
bcc .L_divide_b10
|
||||
cmp r1, r0, lsl #11
|
||||
bcc .L_divide_b11
|
||||
cmp r1, r0, lsl #12
|
||||
bcc .L_divide_b12
|
||||
cmp r1, r0, lsl #13
|
||||
bcc .L_divide_b13
|
||||
cmp r1, r0, lsl #14
|
||||
bcc .L_divide_b14
|
||||
cmp r1, r0, lsl #15
|
||||
bcc .L_divide_b15
|
||||
cmp r1, r0, lsl #16
|
||||
bcc .L_divide_b16
|
||||
cmp r1, r0, lsl #17
|
||||
bcc .L_divide_b17
|
||||
cmp r1, r0, lsl #18
|
||||
bcc .L_divide_b18
|
||||
cmp r1, r0, lsl #19
|
||||
bcc .L_divide_b19
|
||||
cmp r1, r0, lsl #20
|
||||
bcc .L_divide_b20
|
||||
cmp r1, r0, lsl #21
|
||||
bcc .L_divide_b21
|
||||
cmp r1, r0, lsl #22
|
||||
bcc .L_divide_b22
|
||||
cmp r1, r0, lsl #23
|
||||
bcc .L_divide_b23
|
||||
cmp r1, r0, lsl #24
|
||||
bcc .L_divide_b24
|
||||
cmp r1, r0, lsl #25
|
||||
bcc .L_divide_b25
|
||||
cmp r1, r0, lsl #26
|
||||
bcc .L_divide_b26
|
||||
cmp r1, r0, lsl #27
|
||||
bcc .L_divide_b27
|
||||
cmp r1, r0, lsl #28
|
||||
bcc .L_divide_b28
|
||||
cmp r1, r0, lsl #29
|
||||
bcc .L_divide_b29
|
||||
cmp r1, r0, lsl #30
|
||||
bcc .L_divide_b30
|
||||
.L_divide_b32:
|
||||
cmp r1, r0, lsl #31
|
||||
subhs r1, r1,r0, lsl #31
|
||||
addhs r3, r3,r2, lsl #31
|
||||
.L_divide_b31:
|
||||
cmp r1, r0, lsl #30
|
||||
subhs r1, r1,r0, lsl #30
|
||||
addhs r3, r3,r2, lsl #30
|
||||
.L_divide_b30:
|
||||
cmp r1, r0, lsl #29
|
||||
subhs r1, r1,r0, lsl #29
|
||||
addhs r3, r3,r2, lsl #29
|
||||
.L_divide_b29:
|
||||
cmp r1, r0, lsl #28
|
||||
subhs r1, r1,r0, lsl #28
|
||||
addhs r3, r3,r2, lsl #28
|
||||
.L_divide_b28:
|
||||
cmp r1, r0, lsl #27
|
||||
subhs r1, r1,r0, lsl #27
|
||||
addhs r3, r3,r2, lsl #27
|
||||
.L_divide_b27:
|
||||
cmp r1, r0, lsl #26
|
||||
subhs r1, r1,r0, lsl #26
|
||||
addhs r3, r3,r2, lsl #26
|
||||
.L_divide_b26:
|
||||
cmp r1, r0, lsl #25
|
||||
subhs r1, r1,r0, lsl #25
|
||||
addhs r3, r3,r2, lsl #25
|
||||
.L_divide_b25:
|
||||
cmp r1, r0, lsl #24
|
||||
subhs r1, r1,r0, lsl #24
|
||||
addhs r3, r3,r2, lsl #24
|
||||
.L_divide_b24:
|
||||
cmp r1, r0, lsl #23
|
||||
subhs r1, r1,r0, lsl #23
|
||||
addhs r3, r3,r2, lsl #23
|
||||
.L_divide_b23:
|
||||
cmp r1, r0, lsl #22
|
||||
subhs r1, r1,r0, lsl #22
|
||||
addhs r3, r3,r2, lsl #22
|
||||
.L_divide_b22:
|
||||
cmp r1, r0, lsl #21
|
||||
subhs r1, r1,r0, lsl #21
|
||||
addhs r3, r3,r2, lsl #21
|
||||
.L_divide_b21:
|
||||
cmp r1, r0, lsl #20
|
||||
subhs r1, r1,r0, lsl #20
|
||||
addhs r3, r3,r2, lsl #20
|
||||
.L_divide_b20:
|
||||
cmp r1, r0, lsl #19
|
||||
subhs r1, r1,r0, lsl #19
|
||||
addhs r3, r3,r2, lsl #19
|
||||
.L_divide_b19:
|
||||
cmp r1, r0, lsl #18
|
||||
subhs r1, r1,r0, lsl #18
|
||||
addhs r3, r3,r2, lsl #18
|
||||
.L_divide_b18:
|
||||
cmp r1, r0, lsl #17
|
||||
subhs r1, r1,r0, lsl #17
|
||||
addhs r3, r3,r2, lsl #17
|
||||
.L_divide_b17:
|
||||
cmp r1, r0, lsl #16
|
||||
subhs r1, r1,r0, lsl #16
|
||||
addhs r3, r3,r2, lsl #16
|
||||
.L_divide_b16:
|
||||
cmp r1, r0, lsl #15
|
||||
subhs r1, r1,r0, lsl #15
|
||||
addhs r3, r3,r2, lsl #15
|
||||
.L_divide_b15:
|
||||
cmp r1, r0, lsl #14
|
||||
subhs r1, r1,r0, lsl #14
|
||||
addhs r3, r3,r2, lsl #14
|
||||
.L_divide_b14:
|
||||
cmp r1, r0, lsl #13
|
||||
subhs r1, r1,r0, lsl #13
|
||||
addhs r3, r3,r2, lsl #13
|
||||
.L_divide_b13:
|
||||
cmp r1, r0, lsl #12
|
||||
subhs r1, r1,r0, lsl #12
|
||||
addhs r3, r3,r2, lsl #12
|
||||
.L_divide_b12:
|
||||
cmp r1, r0, lsl #11
|
||||
subhs r1, r1,r0, lsl #11
|
||||
addhs r3, r3,r2, lsl #11
|
||||
.L_divide_b11:
|
||||
cmp r1, r0, lsl #10
|
||||
subhs r1, r1,r0, lsl #10
|
||||
addhs r3, r3,r2, lsl #10
|
||||
.L_divide_b10:
|
||||
cmp r1, r0, lsl #9
|
||||
subhs r1, r1,r0, lsl #9
|
||||
addhs r3, r3,r2, lsl #9
|
||||
.L_divide_b9:
|
||||
cmp r1, r0, lsl #8
|
||||
subhs r1, r1,r0, lsl #8
|
||||
addhs r3, r3,r2, lsl #8
|
||||
.L_divide_b8:
|
||||
cmp r1, r0, lsl #7
|
||||
subhs r1, r1,r0, lsl #7
|
||||
addhs r3, r3,r2, lsl #7
|
||||
.L_divide_b7:
|
||||
cmp r1, r0, lsl #6
|
||||
subhs r1, r1,r0, lsl #6
|
||||
addhs r3, r3,r2, lsl #6
|
||||
.L_divide_b6:
|
||||
cmp r1, r0, lsl #5
|
||||
subhs r1, r1,r0, lsl #5
|
||||
addhs r3, r3,r2, lsl #5
|
||||
.L_divide_b5:
|
||||
cmp r1, r0, lsl #4
|
||||
subhs r1, r1,r0, lsl #4
|
||||
addhs r3, r3,r2, lsl #4
|
||||
.L_divide_b4:
|
||||
cmp r1, r0, lsl #3
|
||||
subhs r1, r1,r0, lsl #3
|
||||
addhs r3, r3,r2, lsl #3
|
||||
.L_divide_b3:
|
||||
cmp r1, r0, lsl #2
|
||||
subhs r1, r1,r0, lsl #2
|
||||
addhs r3, r3,r2, lsl #2
|
||||
.L_divide_b2:
|
||||
cmp r1, r0, lsl #1
|
||||
subhs r1, r1,r0, lsl #1
|
||||
addhs r3, r3,r2, lsl #1
|
||||
.L_divide_b1:
|
||||
cmp r1, r0
|
||||
subhs r1, r1, r0
|
||||
addhs r3, r3, r2
|
||||
.L_divide_b0:
|
||||
|
||||
tst ip, #0x20000000
|
||||
bne .L_udivide_l1
|
||||
mov r0, r3
|
||||
cmp ip, #0
|
||||
rsbmi r1, r1, #0
|
||||
movs ip, ip, lsl #1
|
||||
bicmi r0, r0, #0x80000000 /* Fix incase we divided 0x80000000 */
|
||||
rsbmi r0, r0, #0
|
||||
RET
|
||||
|
||||
.L_udivide_l1:
|
||||
tst ip, #0x10000000
|
||||
mov r1, r1, lsl #1
|
||||
orrne r1, r1, #1
|
||||
mov r3, r3, lsl #1
|
||||
cmp r1, r0
|
||||
subhs r1, r1, r0
|
||||
addhs r3, r3, r2
|
||||
mov r0, r3
|
||||
RET
|
||||
|
||||
.L_overflow:
|
||||
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||
#ifdef __ARM_EABI__
|
||||
mov r0, r1 /* return quotient */
|
||||
b PLT_SYM(__aeabi_idiv0)
|
||||
#else
|
||||
mov r0, #8 /* SIGFPE */
|
||||
bl PLT_SYM(_C_LABEL(raise)) /* raise it */
|
||||
mov r0, #0
|
||||
RET
|
||||
#endif
|
||||
#else
|
||||
/* XXX should cause a fatal error */
|
||||
mvn r0, #0
|
||||
RET
|
||||
#endif
|
||||
|
||||
END(__divide)
|
||||
|
||||
#endif /* __ARM_ARCH_EXT_IDIV__ */
|
||||
@@ -1,79 +0,0 @@
|
||||
/* $NetBSD: divsi3.S,v 1.13 2013/09/12 15:36:14 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* 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 <machine/asm.h>
|
||||
|
||||
#if defined(__thumb__) && !defined(_ARM_ARCH_T2)
|
||||
ARM_ENTRY(__divsi3)
|
||||
#else
|
||||
ENTRY(__divsi3)
|
||||
#endif
|
||||
#if defined(__ARM_ARCH_EXT_IDIV__)
|
||||
# if defined(__ARM_EABI__)
|
||||
mov r3, r0 @ save for mls
|
||||
# endif
|
||||
sdiv r0, r0, r1
|
||||
# if defined(__ARM_EABI__)
|
||||
mls r1, r0, r1, r3 @ return modulus in r1
|
||||
# endif
|
||||
RET
|
||||
#elif defined(__ARM_EABI__) && defined(_LIBC)
|
||||
cmp r1, #0 @ dividing by 0?
|
||||
beq .Ldiv0 @ call __aeabi_idiv0
|
||||
ldr r2, .Lhwdiv_present
|
||||
#ifdef __PIC__
|
||||
add r2, r2, pc @ pc = &.LPIC0
|
||||
# endif
|
||||
ldr r2, [r2]
|
||||
.LPIC0: cmp r2, #0
|
||||
beq __divide
|
||||
mov r3, r0
|
||||
# if defined(__ARM_ARCH_EXT_IDIV__)
|
||||
sdiv r0, r0, r1
|
||||
mls r1, r0, r1, r3 @ return modulus in r1
|
||||
# elif defined(__thumb__) && defined(_ARM_ARCH_T2)
|
||||
.inst.w 0xfb90f0f1
|
||||
.inst.w 0xfb003111
|
||||
# else
|
||||
.inst 0xe710f110
|
||||
.inst 0xe0613190
|
||||
# endif
|
||||
RET
|
||||
|
||||
.align 0
|
||||
.Lhwdiv_present:
|
||||
.word REL_SYM(_libc_arm_hwdiv_present, .LPIC0)
|
||||
|
||||
.align 0
|
||||
.Ldiv0: push {r0, lr} /* save r0 */
|
||||
cmp r0, #0
|
||||
mvnge r0, #0x80000000 /* INT_MAX = 0x7fffffff */
|
||||
movlt r0, #0x80000000 /* INT_MIN = 0x80000000 */
|
||||
bl _C_LABEL(__aeabi_idiv0)
|
||||
pop {r1, pc} /* restore r0 as r1 */
|
||||
#else /* !__ARM_EABI__ */
|
||||
b __divide
|
||||
#endif
|
||||
END(__divsi3)
|
||||
|
||||
#if defined(__ARM_EABI__)
|
||||
STRONG_ALIAS(__aeabi_idivmod, __divsi3)
|
||||
STRONG_ALIAS(__aeabi_idiv, __divsi3)
|
||||
#if defined(PIC_SYMVER)
|
||||
.symver __aeabi_idiv,__aeabi_idiv@@GCC_3.5
|
||||
.symver __aeabi_idivmod,__aeabi_idivmod@@GCC_3.5
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,38 +0,0 @@
|
||||
/* $NetBSD: modsi3.S,v 1.4 2013/08/15 21:40:11 matt Exp $ */
|
||||
|
||||
/*
|
||||
* 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 <machine/asm.h>
|
||||
|
||||
#ifndef __ARM_EABI__
|
||||
/*
|
||||
* stack is aligned as there's a possibility of branching to .L_overflow
|
||||
* which makes a C call
|
||||
*/
|
||||
|
||||
ENTRY(__modsi3)
|
||||
#ifdef __ARM_ARCH_EXT_IDIV__
|
||||
sdiv r3, r0, r1
|
||||
mls r0, r3, r1, r0
|
||||
#else
|
||||
str lr, [sp, #-8]! /* push lr */
|
||||
bl PIC_SYM(__divsi3, PLT)
|
||||
mov r0, r1
|
||||
ldr lr, [sp], #8 /* pop lr */
|
||||
#endif
|
||||
RET
|
||||
END(__modsi3)
|
||||
|
||||
#endif
|
||||
@@ -1,74 +0,0 @@
|
||||
/* $NetBSD: udivsi3.S,v 1.9 2013/09/12 15:36:14 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* 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 <machine/asm.h>
|
||||
|
||||
#if defined(__ARM_EABI__) && defined(__thumb__) && !defined(_ARM_ARCH_T2)
|
||||
ARM_ENTRY(__udivsi3)
|
||||
#else
|
||||
ENTRY(__udivsi3)
|
||||
#endif
|
||||
#if defined(__ARM_ARCH_EXT_IDIV__)
|
||||
# if defined(__ARM_EABI__)
|
||||
mov r3, r0 @ save for mls
|
||||
# endif
|
||||
udiv r0, r0, r1
|
||||
# if defined(__ARM_EABI__)
|
||||
mls r1, r0, r1, r3 @ return modulus in r1
|
||||
# endif
|
||||
RET
|
||||
#elif defined(__ARM_EABI__) && defined(_LIBC)
|
||||
cmp r1, #0
|
||||
beq .Ldiv0
|
||||
ldr r2, .Lhwdiv_present
|
||||
#ifdef __PIC__
|
||||
add r2, r2, pc /* pc = &.LPIC0 */
|
||||
# endif
|
||||
ldr r2, [r2]
|
||||
.LPIC0: cmp r2, #0
|
||||
beq __udivide
|
||||
mov r3, r0
|
||||
# if defined(__ARM_ARCH_EXT_IDIV__)
|
||||
udiv r0, r0, r1
|
||||
mls r1, r0, r1, r3 /* return modulus in r1 */
|
||||
# elif defined(__thumb__) && defined(_ARM_ARCH_T2)
|
||||
.inst.w 0xfbb0f0f1
|
||||
.inst.w 0xfb003111
|
||||
# else
|
||||
.inst 0xe730f110
|
||||
.inst 0xe0613190
|
||||
# endif
|
||||
RET
|
||||
|
||||
.align 0
|
||||
.Lhwdiv_present:
|
||||
.word REL_SYM(_libc_arm_hwdiv_present, .LPIC0)
|
||||
|
||||
/* Handle divide by zero */
|
||||
.align 0
|
||||
.Ldiv0: push {r0, lr} /* save r0 */
|
||||
mvns r0, #0 /* thumb2 */
|
||||
bl _C_LABEL(__aeabi_idiv0)
|
||||
pop {r1, pc} /* restore r0 as r1 */
|
||||
#else
|
||||
b __udivide
|
||||
#endif
|
||||
END(__udivsi3)
|
||||
|
||||
#ifdef __ARM_EABI__
|
||||
STRONG_ALIAS(__aeabi_uidivmod, __udivsi3)
|
||||
STRONG_ALIAS(__aeabi_uidiv, __udivsi3)
|
||||
#endif
|
||||
@@ -1,37 +0,0 @@
|
||||
/* $NetBSD: umodsi3.S,v 1.4 2013/08/15 21:40:11 matt Exp $ */
|
||||
|
||||
/*
|
||||
* 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 <machine/asm.h>
|
||||
|
||||
#ifndef __ARM_EABI__
|
||||
/*
|
||||
* stack is aligned as there's a possibility of branching to .L_overflow
|
||||
* which makes a C call
|
||||
*/
|
||||
|
||||
ENTRY(__umodsi3)
|
||||
#ifdef __ARM_ARCH_EXT_IDIV__
|
||||
udiv r3, r0, r1
|
||||
mls r0, r3, r1, r0
|
||||
#else
|
||||
str lr, [sp, #-8]! /* push lr */
|
||||
bl PIC_SYM(__udivsi3, PLT)
|
||||
mov r0, r1
|
||||
ldr lr, [sp], #8 /* pop lr */
|
||||
#endif
|
||||
RET
|
||||
END(__umodsi3)
|
||||
#endif
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: memset.S,v 1.6 2013/11/30 21:09:11 joerg Exp $ */
|
||||
/* $NetBSD: memset.S,v 1.7 2013/12/02 21:21:33 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2003 Wasabi Systems, Inc.
|
||||
@@ -68,8 +68,23 @@
|
||||
|
||||
#include <machine/asm.h>
|
||||
|
||||
#if defined(__ARM_EABI__) && !defined(BZER0)
|
||||
STRONG_ALIAS(__aeabi_memset, memset)
|
||||
#if defined(__ARM_EABI__) && !defined(_BZERO)
|
||||
ENTRY(__aeabi_memset)
|
||||
mov r3, r1
|
||||
mov r1, r2
|
||||
mov r2, r3
|
||||
b memset
|
||||
END(__aeabi_memset)
|
||||
STRONG_ALIAS(__aeabi_memset4, __aeabi_memset)
|
||||
STRONG_ALIAS(__aeabi_memset8, __aeabi_memset)
|
||||
|
||||
ENTRY(__aeabi_memclr)
|
||||
mov r2, r1
|
||||
mov r1, #0
|
||||
b memset
|
||||
END(__aeabi_memclr)
|
||||
STRONG_ALIAS(__aeabi_memclr4, __aeabi_memclr)
|
||||
STRONG_ALIAS(__aeabi_memclr8, __aeabi_memclr)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -15,10 +15,6 @@ __RCSID("$NetBSD: bswap64.c,v 1.3 2009/03/16 05:59:21 cegger Exp $");
|
||||
|
||||
#undef bswap64
|
||||
|
||||
#if defined(__minix) && defined(_STANDALONE)
|
||||
#undef bswap32
|
||||
#endif /* defined(__minix) && defined(_STANDALONE) */
|
||||
|
||||
uint64_t
|
||||
bswap64(uint64_t x)
|
||||
{
|
||||
|
||||
@@ -57,6 +57,10 @@ __RCSID("$NetBSD: sha2.c,v 1.24 2013/06/09 19:46:56 christos Exp $");
|
||||
#include "namespace.h"
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__minix) && defined(_LIBMINC)
|
||||
#include <stdint.h> /* for uintptr_t */
|
||||
#endif /* defined(__minix) && defined(_LIBMINC) */
|
||||
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
@@ -100,6 +100,7 @@ shift $((${OPTIND} - 1))
|
||||
# * ignore var/db/syspkg and its contents
|
||||
# * ignore METALOG and METALOG.*
|
||||
# * ignore etc/mtree/set.*
|
||||
# * MINIX3 only: ignore ASR service binaries
|
||||
#
|
||||
ignore_exceptions()
|
||||
{
|
||||
@@ -107,12 +108,14 @@ IGNORE_REGEXP_SYSPKG="^\./var/db/syspkg(\$|/)"
|
||||
IGNORE_REGEXP_METALOG="^\./METALOG(\..*)?\$"
|
||||
IGNORE_REGEXP_SETS="^\./SETS\..*\$"
|
||||
IGNORE_REGEXP_MTREE="^\./etc/mtree/set\.[a-z]*\$"
|
||||
IGNORE_REGEXP_SERVICE_ASR="^\./usr/service/asr/"
|
||||
|
||||
${EGREP} -v \
|
||||
-e "${IGNORE_REGEXP_SYSPKG}" \
|
||||
-e "${IGNORE_REGEXP_METALOG}" \
|
||||
-e "${IGNORE_REGEXP_SETS}" \
|
||||
-e "${IGNORE_REGEXP_MTREE}"
|
||||
-e "${IGNORE_REGEXP_MTREE}" \
|
||||
-e "${IGNORE_REGEXP_SERVICE_ASR}"
|
||||
}
|
||||
|
||||
#
|
||||
|
||||
@@ -95,12 +95,12 @@
|
||||
./usr/include/i386 minix-sys
|
||||
./usr/lib/libclkconf.a minix-sys
|
||||
./usr/lib/libclkconf_pic.a minix-sys
|
||||
./usr/lib/libc_vfp.a minix-sys
|
||||
./usr/lib/libc_vfp_pic.a minix-sys
|
||||
./usr/lib/libc_vfp.so.0.0 minix-sys
|
||||
./usr/lib/libc_vfp.so.0 minix-sys
|
||||
./usr/lib/libc_vfp.so minix-sys
|
||||
./usr/lib/libgcc_eh.a minix-sys
|
||||
./usr/lib/libc_vfp.a minix-sys obsolete
|
||||
./usr/lib/libc_vfp_pic.a minix-sys obsolete
|
||||
./usr/lib/libc_vfp.so.0.0 minix-sys obsolete
|
||||
./usr/lib/libc_vfp.so.0 minix-sys obsolete
|
||||
./usr/lib/libc_vfp.so minix-sys obsolete
|
||||
./usr/lib/libgcc_eh.a minix-sys gcccmds
|
||||
./usr/lib/libgpio.a minix-sys
|
||||
./usr/lib/libgpio_pic.a minix-sys
|
||||
./usr/lib/libi2cdriver.a minix-sys
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
./etc/system.conf.d/3c90x minix-sys
|
||||
./etc/system.conf.d/atl2 minix-sys
|
||||
./etc/system.conf.d/dec21140A minix-sys
|
||||
./etc/system.conf.d/e1000 minix-sys
|
||||
@@ -6,6 +7,7 @@
|
||||
./etc/system.conf.d/rtl8139 minix-sys
|
||||
./etc/system.conf.d/rtl8169 minix-sys
|
||||
./etc/system.conf.d/virtio_net minix-sys
|
||||
./service/3c90x minix-sys
|
||||
./service/acpi minix-sys
|
||||
./service/ahci minix-sys
|
||||
./service/amddev minix-sys
|
||||
@@ -23,7 +25,7 @@
|
||||
./service/fxp minix-sys
|
||||
./service/hgfs minix-sys
|
||||
./service/lance minix-sys
|
||||
./service/orinoco minix-sys
|
||||
./service/orinoco minix-sys obsolete
|
||||
./service/pci minix-sys
|
||||
./service/pckbd minix-sys
|
||||
./service/printer minix-sys
|
||||
@@ -165,6 +167,8 @@
|
||||
./usr/lib/libvirtio.a minix-sys
|
||||
./usr/lib/libvirtio_pic.a minix-sys
|
||||
./usr/mdec minix-sys
|
||||
./usr/man/man8/hgfs.8 minix-sys
|
||||
./usr/man/man8/vbfs.8 minix-sys
|
||||
./usr/mdec/boot_monitor minix-sys
|
||||
./usr/mdec/bootxx_cd9660 minix-sys
|
||||
./usr/mdec/bootxx_ext2fs minix-sys
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1421,7 +1421,7 @@
|
||||
./usr/X11R7/bin/xconsole -unknown- xorg
|
||||
./usr/X11R7/bin/xcutsel -unknown- xorg
|
||||
./usr/X11R7/bin/xditview -unknown- xorg
|
||||
./usr/X11R7/bin/xdm -unknown- xorg
|
||||
./usr/X11R7/bin/xdm -unknown- xorg,minix-false
|
||||
./usr/X11R7/bin/xdpyinfo -unknown- xorg
|
||||
./usr/X11R7/bin/xdriinfo -unknown- xorg
|
||||
./usr/X11R7/bin/xedit -unknown- xorg
|
||||
@@ -1448,7 +1448,7 @@
|
||||
./usr/X11R7/bin/xload -unknown- xorg
|
||||
./usr/X11R7/bin/xlogo -unknown- xorg
|
||||
./usr/X11R7/bin/xlsatoms -unknown- xorg
|
||||
./usr/X11R7/bin/xlsclients -unknown- xorg
|
||||
./usr/X11R7/bin/xlsclients -unknown- xorg,minix-false
|
||||
./usr/X11R7/bin/xlsfonts -unknown- xorg
|
||||
./usr/X11R7/bin/xmag -unknown- xorg
|
||||
./usr/X11R7/bin/xman -unknown- xorg
|
||||
@@ -1508,14 +1508,14 @@
|
||||
./usr/X11R7/include/X11/extensions base-x11-root xorg
|
||||
./usr/X11R7/include/X11/fonts base-x11-root xorg
|
||||
./usr/X11R7/include/X11/pixmaps base-x11-root xorg
|
||||
./usr/X11R7/include/X11/pixmaps/NetBSD-bw.xpm -unknown- xorg
|
||||
./usr/X11R7/include/X11/pixmaps/NetBSD-flag.png -unknown- xorg
|
||||
./usr/X11R7/include/X11/pixmaps/NetBSD-flag1.xpm -unknown- xorg
|
||||
./usr/X11R7/include/X11/pixmaps/NetBSD-flag2.xpm -unknown- xorg
|
||||
./usr/X11R7/include/X11/pixmaps/NetBSD-inv.xpm -unknown- xorg
|
||||
./usr/X11R7/include/X11/pixmaps/NetBSD.xpm -unknown- xorg
|
||||
./usr/X11R7/include/X11/pixmaps/xorg-bw.xpm -unknown- xorg
|
||||
./usr/X11R7/include/X11/pixmaps/xorg.xpm -unknown- xorg
|
||||
./usr/X11R7/include/X11/pixmaps/NetBSD-bw.xpm -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/X11/pixmaps/NetBSD-flag.png -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/X11/pixmaps/NetBSD-flag1.xpm -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/X11/pixmaps/NetBSD-flag2.xpm -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/X11/pixmaps/NetBSD-inv.xpm -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/X11/pixmaps/NetBSD.xpm -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/X11/pixmaps/xorg-bw.xpm -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/X11/pixmaps/xorg.xpm -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/drm base-x11-root obsolete
|
||||
./usr/X11R7/include/fontconfig base-x11-root xorg
|
||||
./usr/X11R7/include/freetype2 base-x11-root xorg
|
||||
@@ -1538,7 +1538,7 @@
|
||||
./usr/X11R7/lib/X11/app-defaults/Beforelight -unknown- xorg
|
||||
./usr/X11R7/lib/X11/app-defaults/Bitmap -unknown- xorg
|
||||
./usr/X11R7/lib/X11/app-defaults/Bitmap-color -unknown- xorg
|
||||
./usr/X11R7/lib/X11/app-defaults/Chooser -unknown- xorg
|
||||
./usr/X11R7/lib/X11/app-defaults/Chooser -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/X11/app-defaults/Clock-color -unknown- xorg
|
||||
./usr/X11R7/lib/X11/app-defaults/Editres -unknown- xorg
|
||||
./usr/X11R7/lib/X11/app-defaults/Editres-color -unknown- xorg
|
||||
@@ -2478,7 +2478,7 @@
|
||||
./usr/X11R7/lib/xorg base-x11-root xorg
|
||||
./usr/X11R7/lib/xorg/protocol.txt -unknown- xorg
|
||||
./usr/X11R7/libexec base-x11-root xorg
|
||||
./usr/X11R7/libexec/chooser -unknown- xorg
|
||||
./usr/X11R7/libexec/chooser -unknown- xorg,minix-false
|
||||
./usr/X11R7/man base-x11-root xorg
|
||||
./usr/X11R7/man/cat1 base-x11-root xorg
|
||||
./usr/X11R7/man/cat1/appres.0 -unknown- .cat,xorg
|
||||
@@ -2824,7 +2824,7 @@
|
||||
./usr/X11R7/man/man1/xconsole.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/xcutsel.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/xditview.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/xdm.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/xdm.1 -unknown- .man,xorg,minix-false
|
||||
./usr/X11R7/man/man1/xdpyinfo.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/xdriinfo.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/xedit.1 -unknown- .man,xorg
|
||||
@@ -2851,7 +2851,7 @@
|
||||
./usr/X11R7/man/man1/xload.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/xlogo.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/xlsatoms.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/xlsclients.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/xlsclients.1 -unknown- .man,xorg,minix-false
|
||||
./usr/X11R7/man/man1/xlsfonts.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/xmag.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/xman.1 -unknown- .man,xorg
|
||||
|
||||
@@ -333,12 +333,12 @@
|
||||
./usr/X11R7/lib/libpixman-1.so -unknown- xorg
|
||||
./usr/X11R7/lib/libpixman-1.so.2 -unknown- xorg
|
||||
./usr/X11R7/lib/libpixman-1.so.2.2 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-atom.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-atom.so.1 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-atom.so.1.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-aux.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-aux.so.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-aux.so.0.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-atom.so -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-atom.so.1 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-atom.so.1.0 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-aux.so -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-aux.so.0 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-aux.so.0.0 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-composite.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-composite.so.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-composite.so.0.1 -unknown- xorg
|
||||
@@ -351,39 +351,39 @@
|
||||
./usr/X11R7/lib/libxcb-dri2.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-dri2.so.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-dri2.so.0.1 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-event.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-event.so.1 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-event.so.1.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-event.so -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-event.so.1 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-event.so.1.0 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-glx.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-glx.so.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-glx.so.0.1 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-icccm.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-icccm.so.1 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-icccm.so.1.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-image.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-image.so.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-image.so.0.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-keysyms.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-keysyms.so.1 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-keysyms.so.1.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-property.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-property.so.1 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-property.so.1.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-icccm.so -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-icccm.so.1 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-icccm.so.1.0 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-image.so -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-image.so.0 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-image.so.0.0 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-keysyms.so -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-keysyms.so.1 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-keysyms.so.1.0 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-property.so -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-property.so.1 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-property.so.1.0 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-randr.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-randr.so.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-randr.so.0.1 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-record.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-record.so.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-record.so.0.1 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-render-util.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-render-util.so.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-render-util.so.0.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-render-util.so -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-render-util.so.0 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-render-util.so.0.0 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-render.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-render.so.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-render.so.0.1 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-reply.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-reply.so.1 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-reply.so.1.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-reply.so -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-reply.so.1 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-reply.so.1.0 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-res.so -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-res.so.0 -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-res.so.0.1 -unknown- xorg
|
||||
|
||||
@@ -5772,17 +5772,17 @@
|
||||
./usr/X11R7/include/xcb/sync.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xc_misc.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xcb.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xcb_atom.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xcb_aux.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xcb_bitops.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xcb_event.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xcb_icccm.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xcb_image.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xcb_keysyms.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xcb_pixel.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xcb_property.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xcb_renderutil.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xcb_reply.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xcb_atom.h -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/xcb/xcb_aux.h -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/xcb/xcb_bitops.h -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/xcb/xcb_event.h -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/xcb/xcb_icccm.h -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/xcb/xcb_image.h -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/xcb/xcb_keysyms.h -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/xcb/xcb_pixel.h -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/xcb/xcb_property.h -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/xcb/xcb_renderutil.h -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/xcb/xcb_reply.h -unknown- xorg,minix-false
|
||||
./usr/X11R7/include/xcb/xcbext.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xevie.h -unknown- xorg
|
||||
./usr/X11R7/include/xcb/xf86dri.h -unknown- xorg
|
||||
@@ -6208,9 +6208,9 @@
|
||||
./usr/X11R7/lib/libpixman-1_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libre.a -unknown- xorg
|
||||
./usr/X11R7/lib/libre_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-atom.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-atom.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-atom_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-aux.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-aux.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-aux_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-composite.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-composite_p.a -unknown- profile,xorg
|
||||
@@ -6220,27 +6220,27 @@
|
||||
./usr/X11R7/lib/libxcb-dpms_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-dri2.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-dri2_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-event.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-event.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-event_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-glx.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-glx_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-icccm.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-icccm.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-icccm_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-image.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-image.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-image_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-keysyms.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-keysyms.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-keysyms_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-property.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-property.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-property_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-randr.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-randr_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-record.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-record_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-render-util.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-render-util.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-render-util_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-render.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-render_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-reply.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-reply.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-reply_p.a -unknown- profile,xorg
|
||||
./usr/X11R7/lib/libxcb-res.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-res_p.a -unknown- profile,xorg
|
||||
@@ -6315,24 +6315,24 @@
|
||||
./usr/X11R7/lib/pkgconfig/xaw7.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xaw8.pc -obsolete- obsolete
|
||||
./usr/X11R7/lib/pkgconfig/xbitmaps.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-atom.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-aux.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-atom.pc -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/pkgconfig/xcb-aux.pc -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/pkgconfig/xcb-composite.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-damage.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-dpms.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-dri2.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-event.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-event.pc -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/pkgconfig/xcb-glx.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-icccm.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-image.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-keysyms.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-property.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-icccm.pc -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/pkgconfig/xcb-image.pc -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/pkgconfig/xcb-keysyms.pc -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/pkgconfig/xcb-property.pc -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/pkgconfig/xcb-proto.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-randr.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-record.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-render.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-renderutil.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-reply.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-renderutil.pc -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/pkgconfig/xcb-reply.pc -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/pkgconfig/xcb-res.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-screensaver.pc -unknown- xorg
|
||||
./usr/X11R7/lib/pkgconfig/xcb-shape.pc -unknown- xorg
|
||||
|
||||
@@ -105,23 +105,23 @@
|
||||
./usr/X11R7/lib/libpciaccess_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libpixman-1_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libre_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-atom_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-aux_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-atom_pic.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-aux_pic.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-composite_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-damage_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-dpms_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-dri2_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-event_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-event_pic.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-glx_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-icccm_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-image_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-keysyms_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-property_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-icccm_pic.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-image_pic.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-keysyms_pic.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-property_pic.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-randr_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-record_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-render-util_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-render-util_pic.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-render_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-reply_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-reply_pic.a -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/libxcb-res_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-screensaver_pic.a -unknown- xorg
|
||||
./usr/X11R7/lib/libxcb-shape_pic.a -unknown- xorg
|
||||
|
||||
@@ -30,24 +30,24 @@
|
||||
./etc/X11/xdm/TakeConsole -unknown- xorg
|
||||
./etc/X11/xdm/Xaccess -unknown- x11
|
||||
./etc/X11/xdm/Xaccess -unknown- xorg
|
||||
./etc/X11/xdm/Xreset -unknown- xorg
|
||||
./etc/X11/xdm/Xreset -unknown- xorg,minix-false
|
||||
./etc/X11/xdm/Xresources -unknown- x11
|
||||
./etc/X11/xdm/Xresources -unknown- xorg
|
||||
./etc/X11/xdm/Xresources -unknown- xorg,minix-false
|
||||
./etc/X11/xdm/Xservers -unknown- x11
|
||||
./etc/X11/xdm/Xservers -unknown- xorg
|
||||
./etc/X11/xdm/Xservers.fs -unknown- x11
|
||||
./etc/X11/xdm/Xservers.fs -unknown- xorg
|
||||
./etc/X11/xdm/Xservers.ws -unknown- x11
|
||||
./etc/X11/xdm/Xservers.ws -unknown- xorg
|
||||
./etc/X11/xdm/Xservers.ws -unknown- xorg,minix-false
|
||||
./etc/X11/xdm/Xsession -unknown- x11
|
||||
./etc/X11/xdm/Xsession -unknown- xorg
|
||||
./etc/X11/xdm/Xsession -unknown- xorg,minix-false
|
||||
./etc/X11/xdm/Xsetup_0 -unknown- x11
|
||||
./etc/X11/xdm/Xsetup_0 -unknown- xorg
|
||||
./etc/X11/xdm/Xstartup -unknown- xorg
|
||||
./etc/X11/xdm/Xstartup -unknown- xorg,minix-false
|
||||
./etc/X11/xdm/Xwilling -unknown- x11
|
||||
./etc/X11/xdm/Xwilling -unknown- xorg
|
||||
./etc/X11/xdm/xdm-config -unknown- x11
|
||||
./etc/X11/xdm/xdm-config -unknown- xorg
|
||||
./etc/X11/xdm/xdm-config -unknown- xorg,minix-false
|
||||
./etc/X11/xdm/xorg-bw.xpm xetc-obsolete obsolete
|
||||
./etc/X11/xdm/xorg.xpm xetc-obsolete obsolete
|
||||
./etc/X11/xinit/xinitrc -unknown- x11
|
||||
@@ -108,8 +108,8 @@
|
||||
./etc/mtree/set.xetc xetc-sys-root x11
|
||||
./etc/mtree/set.xetc xetc-sys-root xorg
|
||||
./etc/rc.d/fccache etc-x11-rc x11
|
||||
./etc/rc.d/fccache etc-x11-rc xorg
|
||||
./etc/rc.d/fccache etc-x11-rc xorg,minix-false
|
||||
./etc/rc.d/xdm etc-x11-rc x11
|
||||
./etc/rc.d/xdm etc-x11-rc xorg
|
||||
./etc/rc.d/xdm etc-x11-rc xorg,minix-false
|
||||
./etc/rc.d/xfs etc-x11-rc x11
|
||||
./etc/rc.d/xfs etc-x11-rc xorg
|
||||
./etc/rc.d/xfs etc-x11-rc xorg,minix-false
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
./usr/X11R7/lib/modules/drivers/mouse_drv.so.1 -unknown- xorg
|
||||
./usr/X11R7/lib/modules/drivers/void_drv.so -unknown- obsolete
|
||||
./usr/X11R7/lib/modules/drivers/void_drv.so.1 -unknown- obsolete
|
||||
./usr/X11R7/lib/modules/drivers/ws_drv.so -unknown- xorg
|
||||
./usr/X11R7/lib/modules/drivers/ws_drv.so.1 -unknown- xorg
|
||||
./usr/X11R7/lib/modules/drivers/wsfb_drv.so -unknown- xorg
|
||||
./usr/X11R7/lib/modules/drivers/wsfb_drv.so.0 -unknown- xorg
|
||||
./usr/X11R7/lib/modules/drivers/ws_drv.so -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/modules/drivers/ws_drv.so.1 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/modules/drivers/wsfb_drv.so -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/modules/drivers/wsfb_drv.so.0 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/modules/extensions/libdbe.a -unknown- xorg
|
||||
./usr/X11R7/lib/modules/extensions/libdbe.so -unknown- xorg
|
||||
./usr/X11R7/lib/modules/extensions/libdbe.so.0 -unknown- xorg
|
||||
@@ -103,7 +103,7 @@
|
||||
./usr/X11R7/man/man4/kbd.4 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man4/mousedrv.4 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man4/void.4 -unknown- obsolete
|
||||
./usr/X11R7/man/man4/ws.4 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man4/wsfb.4 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man4/ws.4 -unknown- .man,xorg,minix-false
|
||||
./usr/X11R7/man/man4/wsfb.4 -unknown- .man,xorg,minix-false
|
||||
./usr/X11R7/man/man5/xorg.conf.5 -unknown- .man,xorg
|
||||
./usr/X11R7/share/aclocal/xorg-server.m4 -unknown- xorg
|
||||
|
||||
@@ -523,10 +523,10 @@
|
||||
./usr/X11R7/lib/modules/drivers/vmwlegacy_drv.so.11 -unknown- obsolete
|
||||
./usr/X11R7/lib/modules/drivers/void_drv.so -unknown- obsolete
|
||||
./usr/X11R7/lib/modules/drivers/void_drv.so.1 -unknown- obsolete
|
||||
./usr/X11R7/lib/modules/drivers/ws_drv.so -unknown- xorg
|
||||
./usr/X11R7/lib/modules/drivers/ws_drv.so.1 -unknown- xorg
|
||||
./usr/X11R7/lib/modules/drivers/wsfb_drv.so -unknown- xorg
|
||||
./usr/X11R7/lib/modules/drivers/wsfb_drv.so.0 -unknown- xorg
|
||||
./usr/X11R7/lib/modules/drivers/ws_drv.so -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/modules/drivers/ws_drv.so.1 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/modules/drivers/wsfb_drv.so -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/modules/drivers/wsfb_drv.so.0 -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/modules/drivers/xgi_drv.so -unknown- xorg
|
||||
./usr/X11R7/lib/modules/drivers/xgi_drv.so.1 -unknown- xorg
|
||||
./usr/X11R7/lib/modules/extensions/libGLcore.a -unknown- obsolete
|
||||
@@ -775,8 +775,8 @@
|
||||
./usr/X11R7/man/man4/vmmouse.4 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man4/vmware.4 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man4/void.4 -unknown- obsolete
|
||||
./usr/X11R7/man/man4/ws.4 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man4/wsfb.4 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man4/ws.4 -unknown- .man,xorg,minix-false
|
||||
./usr/X11R7/man/man4/wsfb.4 -unknown- .man,xorg,minix-false
|
||||
./usr/X11R7/man/man4/xgi.4 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man5/xorg.conf.5 -unknown- .man,xorg
|
||||
./usr/X11R7/share/aclocal/xorg-server.m4 -unknown- xorg
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
./usr/X11R6/man/man1/xdmxconfig.1 -unknown- .man,x11
|
||||
./usr/X11R6/man/man1/xvidtune.1 -unknown- .man,x11
|
||||
./usr/X11R7/bin/Xnest -unknown- xorg
|
||||
./usr/X11R7/bin/Xvfb -unknown- xorg
|
||||
./usr/X11R7/bin/Xvfb -unknown- xorg,minix-false
|
||||
./usr/X11R7/lib/modules/dri/libmesa_dri.so -unknown- xorg
|
||||
./usr/X11R7/lib/modules/dri/libmesa_dri.so.0 -unknown- xorg
|
||||
./usr/X11R7/lib/modules/dri/swrast_dri.so -unknown- xorg
|
||||
@@ -71,5 +71,5 @@
|
||||
./usr/X11R7/man/man1/Xmark.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/Xnest.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/Xserver.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/Xvfb.1 -unknown- .man,xorg
|
||||
./usr/X11R7/man/man1/Xvfb.1 -unknown- .man,xorg,minix-false
|
||||
./usr/X11R7/man/man5/SecurityPolicy.5 -unknown- obsolete
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
20150623:
|
||||
In order to use the new Unix98 PTYs, and to ensure that the test set
|
||||
continues to pass, please add the following line to your /etc/fstab:
|
||||
|
||||
"none /dev/pts ptyfs rw,rslabel=ptyfs 0 0"
|
||||
|
||||
20140801:
|
||||
As the ABI went under heavy changes it is not possible to do a source
|
||||
upgrade (make build) between:
|
||||
|
||||
17
etc/Makefile
17
etc/Makefile
@@ -275,7 +275,8 @@ CONFIGSYMLINKS+= ${TZDIR}/${LOCALTIME} /etc/localtime \
|
||||
CONFIGSYMLINKS+= \
|
||||
/usr/log /var/log \
|
||||
/usr/tmp /var/tmp \
|
||||
/proc/mounts /etc/mtab
|
||||
/proc/mounts /etc/mtab \
|
||||
/usr/service/asr /service/asr
|
||||
|
||||
.endif # !defined(__MINIX)
|
||||
|
||||
@@ -308,7 +309,11 @@ install-etc-files: .PHONY .MAKE check_DESTDIR MAKEDEV
|
||||
${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ resolv.conf \
|
||||
${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ motd \
|
||||
${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ rc.conf \
|
||||
${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ profile
|
||||
${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ shrc \
|
||||
${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ csh.cshrc \
|
||||
${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ csh.login \
|
||||
${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ csh.logout \
|
||||
${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ profile
|
||||
${_MKMSG_INSTALL} ${DESTDIR}${tdir}${files:T}
|
||||
if [ ! -e ${tdir} ]; then \
|
||||
${INSTALL_DIR} ${tdir}; \
|
||||
@@ -351,7 +356,11 @@ install-etc-files-safe: .PHONY .MAKE check_DESTDIR MAKEDEV
|
||||
${ETC_INSTALL_OBJ_FILE} -o ${BINOWN} -g ${BINGRP} -m 555 \
|
||||
MAKEDEV ${DESTDIR}/dev
|
||||
.else
|
||||
# As /var/log is a symlink to /usr/log, we need to use /usr/log for files
|
||||
# in /var/log here. The same applies to the distrib list entries.
|
||||
.for owner group mode file in \
|
||||
${BINOWN} ${BINGRP} 644 /usr/log/messages \
|
||||
${BINOWN} ${BINGRP} 644 /usr/log/syslog \
|
||||
games games 664 /var/games/tetris.scores
|
||||
${_MKMSG_INSTALL} ${DESTDIR}${file}
|
||||
if [ ! -e ${DESTDIR}${file} -o -s ${DESTDIR}${file} ]; then \
|
||||
@@ -434,8 +443,6 @@ install-etc-files-safe: .PHONY .MAKE check_DESTDIR MAKEDEV
|
||||
${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/devmand/ ${DESTDIR}/etc/devmand/ usb_storage.cfg \
|
||||
${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/devmand/scripts/ ${DESTDIR}/etc/devmand/scripts/ block \
|
||||
${BINOWN} ${BINGRP} ${BINMODE} ${NETBSDSRCDIR}/etc/devmand/scripts/ ${DESTDIR}/etc/devmand/scripts/ singlechar \
|
||||
${BINOWN} ${BINGRP} ${NONBINMODE} ${NETBSDSRCDIR}/etc/ast/ ${DESTDIR}/usr/ast/ .[aepv]* \
|
||||
${BINOWN} ${BINGRP} ${NONBINMODE} ${NETBSDSRCDIR}/etc/ast/ ${DESTDIR}/root/ .[aepv]* \
|
||||
|
||||
${_MKMSG_INSTALL} ${DESTDIR}${tdir}${files:T}
|
||||
if [ ! -e ${tdir} ]; then \
|
||||
@@ -449,7 +456,7 @@ install-etc-files-safe: .PHONY .MAKE check_DESTDIR MAKEDEV
|
||||
${INSTALL_FILE} -m ${BINMODE} -o ${BINOWN} -g ${BINGRP} ${NETBSDSRCDIR}/etc/rc.capes/* ${DESTDIR}/etc/rc.capes
|
||||
${INSTALL_FILE} -m ${BINMODE} -o ${BINOWN} -g ${BINGRP} ${NETBSDSRCDIR}/minix/drivers/usb/usbd/usbd.conf ${DESTDIR}/etc/system.conf.d/usbd
|
||||
.endif # Minix/earm specific
|
||||
.for subdir in . defaults mtree
|
||||
.for subdir in . defaults mtree root skel
|
||||
${MAKEDIRTARGET} ${subdir} configinstall
|
||||
.endfor
|
||||
${_MKMSG_INSTALL} ${DESTDIR}/usr/lib/fonts
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
set autoindent autowrite report=2 showmatch
|
||||
@@ -1,33 +0,0 @@
|
||||
# Login shell profile.
|
||||
|
||||
umask 022
|
||||
|
||||
# Favourite editor and pager, search path for binaries, etc.
|
||||
export EDITOR=vi
|
||||
export PAGER=less
|
||||
|
||||
# Let cd display the current directory on the status line.
|
||||
if [ -t 0 -a -f /usr/bin/tget ] && tget -flag hs
|
||||
then
|
||||
case $- in *i*)
|
||||
hostname=$(expr $(uname -n) : '\([^.]*\)')
|
||||
eval "cd()
|
||||
{
|
||||
chdir \"\$@\" &&
|
||||
echo -n '$(tget -str ts \
|
||||
"$USER@$hostname:'\"\`pwd\`\"'" \
|
||||
-str fs)'
|
||||
}"
|
||||
unset hostname
|
||||
cd .
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Check terminal type.
|
||||
case $TERM in
|
||||
dialup|unknown|network)
|
||||
echo -n "Terminal type? ($TERM) "; read term
|
||||
TERM="${term:-$TERM}"
|
||||
unset term
|
||||
esac
|
||||
3
etc/csh.cshrc
Normal file
3
etc/csh.cshrc
Normal file
@@ -0,0 +1,3 @@
|
||||
# $NetBSD: csh.cshrc,v 1.2 1996/05/08 17:19:27 thorpej Exp $
|
||||
#
|
||||
# System-wide .cshrc file for csh(1).
|
||||
3
etc/csh.login
Normal file
3
etc/csh.login
Normal file
@@ -0,0 +1,3 @@
|
||||
# $NetBSD: csh.login,v 1.2 1996/05/08 17:19:28 thorpej Exp $
|
||||
#
|
||||
# System-wide .login file for csh(1).
|
||||
3
etc/csh.logout
Normal file
3
etc/csh.logout
Normal file
@@ -0,0 +1,3 @@
|
||||
# $NetBSD: csh.logout,v 1.2 1996/05/08 17:19:31 thorpej Exp $
|
||||
#
|
||||
# System-wide .logout file for csh(1).
|
||||
@@ -4,7 +4,8 @@
|
||||
_version BSD.2
|
||||
|
||||
# The whatis/apropos database.
|
||||
_mandb /var/db/man.db
|
||||
# MINIX: Use the correct variable for the DB path
|
||||
_whatdb /usr/man/whatis.db
|
||||
|
||||
# Subdirectories for paths ending in '/', IN SEARCH ORDER.
|
||||
_subdir cat1 man1 cat8 man8 cat6 man6 cat2 man2 cat3 cat3lua man3 man3lua cat4 man4 cat5 man5 cat7 man7 man3f cat9 cat9lua man9 man9lua catn mann catl manl
|
||||
|
||||
204
etc/mtree/NetBSD.dist.Xorg
Normal file
204
etc/mtree/NetBSD.dist.Xorg
Normal file
@@ -0,0 +1,204 @@
|
||||
# $NetBSD: NetBSD.dist.Xorg,v 1.12 2013/06/10 05:09:34 mrg Exp $
|
||||
|
||||
# LSC Do not take for granted that the last thing done in the previous file
|
||||
# was standard directories...
|
||||
/set type=dir uid=0 gid=0 mode=0755
|
||||
|
||||
./etc/fonts
|
||||
./etc/fonts/conf.avail
|
||||
./etc/X11
|
||||
./etc/X11/fs
|
||||
./etc/X11/lbxproxy
|
||||
./etc/X11/proxymngr
|
||||
./etc/X11/rstart
|
||||
./etc/X11/rstart/commands
|
||||
./etc/X11/rstart/commands/x11r6
|
||||
./etc/X11/rstart/contexts
|
||||
./etc/X11/twm
|
||||
./etc/X11/xdm
|
||||
./etc/X11/xinit
|
||||
./etc/X11/xserver
|
||||
./etc/X11/xsm
|
||||
./usr/libdata
|
||||
./usr/libdata/debug
|
||||
./usr/libdata/debug/usr
|
||||
./usr/X11R7
|
||||
./usr/X11R7/bin
|
||||
./usr/X11R7/include
|
||||
./usr/X11R7/include/DPS
|
||||
./usr/X11R7/include/GL
|
||||
./usr/X11R7/include/GL/internal
|
||||
./usr/X11R7/include/X11
|
||||
./usr/X11R7/include/X11/dri
|
||||
./usr/X11R7/include/X11/ICE
|
||||
./usr/X11R7/include/X11/PM
|
||||
./usr/X11R7/include/X11/SM
|
||||
./usr/X11R7/include/X11/Xaw
|
||||
./usr/X11R7/include/X11/Xcursor
|
||||
./usr/X11R7/include/X11/Xft
|
||||
./usr/X11R7/include/X11/Xmu
|
||||
./usr/X11R7/include/X11/Xtrans
|
||||
./usr/X11R7/include/X11/bitmaps
|
||||
./usr/X11R7/include/X11/extensions
|
||||
./usr/X11R7/include/X11/fonts
|
||||
./usr/X11R7/include/X11/pixmaps
|
||||
./usr/X11R7/include/libdrm
|
||||
./usr/X11R7/include/libkms
|
||||
./usr/X11R7/include/fontconfig
|
||||
./usr/X11R7/include/freetype2
|
||||
./usr/X11R7/include/freetype2/freetype
|
||||
./usr/X11R7/include/freetype2/freetype/cache
|
||||
./usr/X11R7/include/freetype2/freetype/config
|
||||
./usr/X11R7/include/freetype2/freetype/internal
|
||||
./usr/X11R7/include/freetype2/freetype/internal/services
|
||||
./usr/X11R7/include/pixman-1
|
||||
./usr/X11R7/include/xcb
|
||||
./usr/X11R7/include/xorg
|
||||
./usr/X11R7/lib
|
||||
./usr/X11R7/lib/X11
|
||||
./usr/X11R7/lib/X11/app-defaults
|
||||
./usr/X11R7/lib/X11/config
|
||||
./usr/X11R7/lib/X11/doc
|
||||
./usr/X11R7/lib/X11/etc
|
||||
./usr/X11R7/lib/X11/fonts
|
||||
./usr/X11R7/lib/X11/fonts/100dpi
|
||||
./usr/X11R7/lib/X11/fonts/75dpi
|
||||
./usr/X11R7/lib/X11/fonts/CID
|
||||
./usr/X11R7/lib/X11/fonts/Speedo
|
||||
./usr/X11R7/lib/X11/fonts/TTF
|
||||
./usr/X11R7/lib/X11/fonts/Type1
|
||||
./usr/X11R7/lib/X11/fonts/cyrillic
|
||||
./usr/X11R7/lib/X11/fonts/encodings
|
||||
./usr/X11R7/lib/X11/fonts/encodings/large
|
||||
./usr/X11R7/lib/X11/fonts/local
|
||||
./usr/X11R7/lib/X11/fonts/misc
|
||||
./usr/X11R7/lib/X11/fonts/util
|
||||
./usr/X11R7/lib/X11/locale
|
||||
./usr/X11R7/lib/X11/locale/C
|
||||
./usr/X11R7/lib/X11/locale/am_ET.UTF-8
|
||||
./usr/X11R7/lib/X11/locale/armscii-8
|
||||
./usr/X11R7/lib/X11/locale/el_GR.UTF-8
|
||||
./usr/X11R7/lib/X11/locale/en_US.UTF-8
|
||||
./usr/X11R7/lib/X11/locale/georgian-academy
|
||||
./usr/X11R7/lib/X11/locale/georgian-ps
|
||||
./usr/X11R7/lib/X11/locale/ibm-cp1133
|
||||
./usr/X11R7/lib/X11/locale/iscii-dev
|
||||
./usr/X11R7/lib/X11/locale/isiri-3342
|
||||
./usr/X11R7/lib/X11/locale/iso8859-1
|
||||
./usr/X11R7/lib/X11/locale/iso8859-10
|
||||
./usr/X11R7/lib/X11/locale/iso8859-11
|
||||
./usr/X11R7/lib/X11/locale/iso8859-13
|
||||
./usr/X11R7/lib/X11/locale/iso8859-14
|
||||
./usr/X11R7/lib/X11/locale/iso8859-15
|
||||
./usr/X11R7/lib/X11/locale/iso8859-2
|
||||
./usr/X11R7/lib/X11/locale/iso8859-3
|
||||
./usr/X11R7/lib/X11/locale/iso8859-4
|
||||
./usr/X11R7/lib/X11/locale/iso8859-5
|
||||
./usr/X11R7/lib/X11/locale/iso8859-6
|
||||
./usr/X11R7/lib/X11/locale/iso8859-7
|
||||
./usr/X11R7/lib/X11/locale/iso8859-8
|
||||
./usr/X11R7/lib/X11/locale/iso8859-9
|
||||
./usr/X11R7/lib/X11/locale/iso8859-9e
|
||||
./usr/X11R7/lib/X11/locale/ja
|
||||
./usr/X11R7/lib/X11/locale/ja.JIS
|
||||
./usr/X11R7/lib/X11/locale/ja.SJIS
|
||||
./usr/X11R7/lib/X11/locale/ja_JP.UTF-8
|
||||
./usr/X11R7/lib/X11/locale/ko
|
||||
./usr/X11R7/lib/X11/locale/ko_KR.UTF-8
|
||||
./usr/X11R7/lib/X11/locale/koi8-c
|
||||
./usr/X11R7/lib/X11/locale/koi8-r
|
||||
./usr/X11R7/lib/X11/locale/koi8-u
|
||||
./usr/X11R7/lib/X11/locale/lib
|
||||
./usr/X11R7/lib/X11/locale/lib/common
|
||||
./usr/X11R7/lib/X11/locale/microsoft-cp1251
|
||||
./usr/X11R7/lib/X11/locale/microsoft-cp1255
|
||||
./usr/X11R7/lib/X11/locale/microsoft-cp1256
|
||||
./usr/X11R7/lib/X11/locale/mulelao-1
|
||||
./usr/X11R7/lib/X11/locale/nokhchi-1
|
||||
./usr/X11R7/lib/X11/locale/pt_BR.UTF-8
|
||||
./usr/X11R7/lib/X11/locale/tatar-cyr
|
||||
./usr/X11R7/lib/X11/locale/th_TH
|
||||
./usr/X11R7/lib/X11/locale/th_TH.UTF-8
|
||||
./usr/X11R7/lib/X11/locale/tscii-0
|
||||
./usr/X11R7/lib/X11/locale/vi_VN.tcvn
|
||||
./usr/X11R7/lib/X11/locale/vi_VN.viscii
|
||||
./usr/X11R7/lib/X11/locale/zh_CN
|
||||
./usr/X11R7/lib/X11/locale/zh_CN.UTF-8
|
||||
./usr/X11R7/lib/X11/locale/zh_CN.gb18030
|
||||
./usr/X11R7/lib/X11/locale/zh_CN.gbk
|
||||
./usr/X11R7/lib/X11/locale/zh_HK.UTF-8
|
||||
./usr/X11R7/lib/X11/locale/zh_HK.big5
|
||||
./usr/X11R7/lib/X11/locale/zh_HK.big5hkscs
|
||||
./usr/X11R7/lib/X11/locale/zh_TW
|
||||
./usr/X11R7/lib/X11/locale/zh_TW.UTF-8
|
||||
./usr/X11R7/lib/X11/locale/zh_TW.big5
|
||||
./usr/X11R7/lib/X11/x11perfcomp
|
||||
./usr/X11R7/lib/X11/xedit
|
||||
./usr/X11R7/lib/X11/xedit/lisp
|
||||
./usr/X11R7/lib/X11/xedit/lisp/progmodes
|
||||
./usr/X11R7/lib/X11/xkb
|
||||
./usr/X11R7/lib/X11/xkb/compat
|
||||
./usr/X11R7/lib/X11/xkb/geometry
|
||||
./usr/X11R7/lib/X11/xkb/geometry/digital_vndr
|
||||
./usr/X11R7/lib/X11/xkb/geometry/sgi_vndr
|
||||
./usr/X11R7/lib/X11/xkb/keycodes
|
||||
./usr/X11R7/lib/X11/xkb/keycodes/digital_vndr
|
||||
./usr/X11R7/lib/X11/xkb/keycodes/sgi_vndr
|
||||
./usr/X11R7/lib/X11/xkb/rules
|
||||
./usr/X11R7/lib/X11/xkb/symbols
|
||||
./usr/X11R7/lib/X11/xkb/symbols/digital_vndr
|
||||
./usr/X11R7/lib/X11/xkb/symbols/fujitsu_vndr
|
||||
./usr/X11R7/lib/X11/xkb/symbols/hp_vndr
|
||||
./usr/X11R7/lib/X11/xkb/symbols/macintosh_vndr
|
||||
./usr/X11R7/lib/X11/xkb/symbols/nec_vndr
|
||||
./usr/X11R7/lib/X11/xkb/symbols/nokia_vndr
|
||||
./usr/X11R7/lib/X11/xkb/symbols/sgi_vndr
|
||||
./usr/X11R7/lib/X11/xkb/symbols/sharp_vndr
|
||||
./usr/X11R7/lib/X11/xkb/symbols/sony_vndr
|
||||
./usr/X11R7/lib/X11/xkb/symbols/sun_vndr
|
||||
./usr/X11R7/lib/X11/xkb/symbols/xfree68_vndr
|
||||
./usr/X11R7/lib/X11/xkb/torture
|
||||
./usr/X11R7/lib/X11/xkb/types
|
||||
./usr/X11R7/lib/modules
|
||||
./usr/X11R7/lib/modules/dri
|
||||
./usr/X11R7/lib/modules/extensions
|
||||
./usr/X11R7/lib/modules/fonts
|
||||
./usr/X11R7/lib/modules/drivers
|
||||
./usr/X11R7/lib/modules/input
|
||||
./usr/X11R7/lib/pkgconfig
|
||||
./usr/X11R7/lib/xorg
|
||||
./usr/X11R7/libexec
|
||||
./usr/X11R7/man
|
||||
./usr/X11R7/man/cat1
|
||||
./usr/X11R7/man/cat3
|
||||
./usr/X11R7/man/cat4
|
||||
./usr/X11R7/man/cat5
|
||||
./usr/X11R7/man/cat7
|
||||
./usr/X11R7/man/html1
|
||||
./usr/X11R7/man/html3
|
||||
./usr/X11R7/man/html4
|
||||
./usr/X11R7/man/html5
|
||||
./usr/X11R7/man/html7
|
||||
./usr/X11R7/man/man1
|
||||
./usr/X11R7/man/man3
|
||||
./usr/X11R7/man/man4
|
||||
./usr/X11R7/man/man5
|
||||
./usr/X11R7/man/man7
|
||||
./usr/X11R7/share
|
||||
./usr/X11R7/share/aclocal
|
||||
./usr/X11R7/share/examples
|
||||
./usr/X11R7/share/examples/ssh-askpass
|
||||
./usr/X11R7/share/pciids
|
||||
./usr/X11R7/share/xcb
|
||||
./usr/libdata/debug/usr/X11R7
|
||||
./usr/libdata/debug/usr/X11R7/bin
|
||||
./usr/libdata/debug/usr/X11R7/lib
|
||||
./usr/libdata/debug/usr/X11R7/lib/X11
|
||||
./usr/libdata/debug/usr/X11R7/lib/X11/locale
|
||||
./usr/libdata/debug/usr/X11R7/lib/X11/locale/lib
|
||||
./usr/libdata/debug/usr/X11R7/lib/X11/locale/lib/common
|
||||
./usr/libdata/debug/usr/X11R7/lib/modules
|
||||
./usr/libdata/debug/usr/X11R7/lib/modules/dri
|
||||
./usr/libdata/debug/usr/X11R7/lib/modules/drivers
|
||||
./usr/libdata/debug/usr/X11R7/lib/modules/extensions
|
||||
./usr/libdata/debug/usr/X11R7/libexec
|
||||
@@ -17,11 +17,29 @@
|
||||
./boot/minix
|
||||
./boot/minix_default
|
||||
./dev
|
||||
./dev/pts
|
||||
./etc
|
||||
./etc/X11
|
||||
./etc/X11/fs
|
||||
./etc/X11/lbxproxy
|
||||
./etc/X11/proxymngr
|
||||
./etc/X11/rstart
|
||||
./etc/X11/rstart/commands
|
||||
./etc/X11/rstart/commands/x11r6
|
||||
./etc/X11/rstart/contexts
|
||||
./etc/X11/twm
|
||||
./etc/X11/xdm
|
||||
./etc/X11/xinit
|
||||
./etc/X11/xserver
|
||||
./etc/X11/xsm
|
||||
./etc/defaults
|
||||
./etc/devmand
|
||||
./etc/devmand/scripts
|
||||
./etc/fonts
|
||||
./etc/fonts/conf.avail
|
||||
./etc/fonts/conf.d
|
||||
./etc/mtree
|
||||
./etc/skel
|
||||
./etc/system.conf.d
|
||||
./home
|
||||
./lib
|
||||
@@ -34,15 +52,8 @@
|
||||
./usr
|
||||
./usr/adm
|
||||
./usr/adm/old
|
||||
./usr/ast
|
||||
./usr/bin
|
||||
./usr/etc
|
||||
./usr/benchmarks
|
||||
./usr/benchmarks/unixbench
|
||||
./usr/benchmarks/unixbench/pgms
|
||||
./usr/benchmarks/unixbench/tmp
|
||||
./usr/benchmarks/unixbench/testdir
|
||||
./usr/benchmarks/unixbench/results
|
||||
./usr/games
|
||||
./usr/games/hide gname=games mode=0750
|
||||
./usr/include
|
||||
@@ -52,6 +63,9 @@
|
||||
./usr/include/compat/machine
|
||||
./usr/include/ddekit
|
||||
./usr/include/ddekit/minix
|
||||
./usr/include/dev
|
||||
./usr/include/dev/pci
|
||||
./usr/include/event2
|
||||
./usr/include/fs
|
||||
./usr/include/g++
|
||||
./usr/include/i386
|
||||
@@ -91,7 +105,6 @@
|
||||
./usr/log
|
||||
./usr/man
|
||||
./usr/man/man1
|
||||
./usr/man/man1x
|
||||
./usr/man/man2
|
||||
./usr/man/man3
|
||||
./usr/man/man4
|
||||
@@ -107,6 +120,8 @@
|
||||
./usr/preserve
|
||||
./usr/run
|
||||
./usr/sbin
|
||||
./usr/service
|
||||
./usr/service/asr
|
||||
./usr/share
|
||||
./usr/share/calendar
|
||||
./usr/share/doc
|
||||
@@ -116,10 +131,15 @@
|
||||
./usr/share/doc/psd/19.curses
|
||||
./usr/share/doc/usd
|
||||
./usr/share/doc/usd/03.shell
|
||||
./usr/share/doc/usd/04.csh
|
||||
./usr/share/doc/usd/30.rogue
|
||||
./usr/share/examples
|
||||
./usr/share/examples/tmux
|
||||
./usr/share/info
|
||||
./usr/share/games
|
||||
./usr/share/games/fortune
|
||||
./usr/share/misc
|
||||
./usr/share/legal
|
||||
./usr/share/mk
|
||||
./usr/share/nvi
|
||||
./usr/share/nvi/catalog
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#
|
||||
# $NetBSD: NetBSD.dist.earm,v 1.1 2013/04/27 07:59:09 matt Exp $
|
||||
|
||||
./usr/share/beaglebone
|
||||
./usr/share/beaglebone/weather
|
||||
|
||||
@@ -162,7 +162,6 @@
|
||||
./usr/share/doc/kyua-atf-compat
|
||||
./usr/share/doc/kyua-cli
|
||||
./usr/share/doc/kyua-testers
|
||||
./usr/share/examples
|
||||
./usr/share/examples/atf
|
||||
./usr/share/examples/kyua-cli
|
||||
./usr/share/examples/lutok
|
||||
|
||||
31
etc/profile
31
etc/profile
@@ -1,28 +1,10 @@
|
||||
# Default system-wide login shell profile.
|
||||
|
||||
# Activate emacs keybindings and command line history support
|
||||
set -o emacs
|
||||
set -o tabcomplete
|
||||
|
||||
# Set the default path
|
||||
PATH=/usr/local/bin:/usr/pkg/bin:/usr/bin:/bin:/usr/games
|
||||
|
||||
# Add ~/bin, iff it is present
|
||||
if [ -e ${HOME}/bin ]; then
|
||||
PATH=${HOME}/bin:${PATH}
|
||||
fi
|
||||
|
||||
# Add sbin for root
|
||||
if [ "x$(id -u)" = "x0" ]; then
|
||||
PATH=/usr/local/sbin:/usr/pkg/sbin:/usr/sbin:/sbin:${PATH}
|
||||
|
||||
if [ -e ${HOME}/sbin ]; then
|
||||
PATH=${HOME}/sbin:${PATH}
|
||||
fi
|
||||
fi
|
||||
# $NetBSD: profile,v 1.1 1997/06/21 06:07:39 mikel Exp $
|
||||
#
|
||||
# System-wide .profile file for sh(1).
|
||||
|
||||
# MINIX specifics
|
||||
# Set library path
|
||||
export LD_LIBRARY_PATH="/usr/local/lib:/usr/pkg/lib:/usr/lib:/lib"
|
||||
export LD_LIBRARY_PATH="/lib:/usr/lib:/usr/X11R7/lib:/usr/pkg/lib:/usr/local/lib"
|
||||
|
||||
# Set the timezone
|
||||
export TZ=GMT0
|
||||
@@ -32,5 +14,4 @@ if [ -f ${RC_TZ} ]; then
|
||||
. ${RC_TZ}
|
||||
fi
|
||||
|
||||
export PATH TZ
|
||||
|
||||
export TZ
|
||||
|
||||
7
etc/rc
7
etc/rc
@@ -158,6 +158,13 @@ autoboot|start)
|
||||
edit memory
|
||||
edit pfs
|
||||
edit init
|
||||
#
|
||||
# Keep a copy around to recover the root FS from crashes
|
||||
#
|
||||
rootline=`cat /etc/mtab | grep "on / "`
|
||||
rootfs=fs_`echo "$rootline" | cut -d' ' -f1 | cut -d'/' -f3`
|
||||
roottype=`echo "$rootline" | cut -d' ' -f5`
|
||||
service -c edit /service/$roottype -label $rootfs
|
||||
fi
|
||||
|
||||
if [ "$sflag" ]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
daemonize talkd
|
||||
daemonize tcpd shell in.rshd
|
||||
daemonize tcpd shell /usr/libexec/rshd
|
||||
daemonize tcpd telnet in.telnetd
|
||||
daemonize tcpd ftp /usr/libexec/ftpd
|
||||
daemonize tcpd finger /usr/libexec/fingerd
|
||||
|
||||
19
etc/root/Makefile
Normal file
19
etc/root/Makefile
Normal file
@@ -0,0 +1,19 @@
|
||||
# $NetBSD: Makefile,v 1.4 2012/11/17 23:08:38 uwe Exp $
|
||||
|
||||
CONFIGFILES= dot.cshrc dot.klogin dot.login dot.profile dot.shrc
|
||||
|
||||
FILESDIR= /root
|
||||
FILESMODE= 644
|
||||
FILESMODE_dot.klogin= 600
|
||||
.for F in ${CONFIGFILES}
|
||||
FILESNAME_${F}= ${F:S/dot//}
|
||||
.endfor
|
||||
|
||||
.include <bsd.own.mk>
|
||||
.if !defined(__MINIX)
|
||||
CONFIGLINKS= /root/.cshrc /.cshrc \
|
||||
/root/.profile /.profile
|
||||
.endif # !defined(__MINIX)
|
||||
|
||||
.include <bsd.files.mk>
|
||||
.include <bsd.links.mk>
|
||||
43
etc/root/dot.cshrc
Normal file
43
etc/root/dot.cshrc
Normal file
@@ -0,0 +1,43 @@
|
||||
# $NetBSD: dot.cshrc,v 1.24 2012/03/11 17:28:47 he Exp $
|
||||
|
||||
alias h history
|
||||
alias j jobs -l
|
||||
alias hup '( set pid=$< ; kill -HUP $pid ) < /var/run/\!$.pid'
|
||||
alias la ls -a
|
||||
alias lf ls -FA
|
||||
alias ll ls -l
|
||||
|
||||
alias x exit
|
||||
alias z suspend
|
||||
|
||||
alias back 'set back="$old"; set old="$cwd"; cd "$back"; unset back; dirs'
|
||||
alias cd 'set old="$cwd"; chdir \!*'
|
||||
alias pd pushd
|
||||
alias pd2 pushd +2
|
||||
alias pd3 pushd +3
|
||||
alias pd4 pushd +4
|
||||
alias tset 'set noglob histchars=""; eval `\tset -s \!*`; unset noglob histchars'
|
||||
|
||||
setenv BLOCKSIZE 1k
|
||||
|
||||
# Uncomment the following line(s) to install binary packages
|
||||
# from ftp.NetBSD.org via pkg_add. (See also pkg_install.conf)
|
||||
#setenv PKG_PATH "ftp://ftp.NetBSD.org/pub/pkgsrc/packages/NetBSD/`uname -m`/6.0/All"
|
||||
#setenv PKG_PATH "${PKG_PATH};ftp://ftp.NetBSD.org/pub/pkgsrc/packages/NetBSD/`uname -m`/5.1/All"
|
||||
#setenv PKG_PATH "${PKG_PATH};ftp://ftp.NetBSD.org/pub/pkgsrc/packages/NetBSD/`uname -m`/5.0/All"
|
||||
|
||||
set history=1000
|
||||
set path=(/sbin /usr/sbin /bin /usr/bin /usr/pkg/sbin /usr/pkg/bin /usr/X11R7/bin /usr/X11R6/bin /usr/local/sbin /usr/local/bin)
|
||||
|
||||
# directory stuff: cdpath/cd/back
|
||||
set cdpath=(/usr/src/{sys,bin,sbin,usr.{bin,sbin},lib,libexec,share,local,games,gnu/{usr.{bin,sbin},libexec,lib,games}})
|
||||
|
||||
if ($?prompt && -x /usr/bin/id ) then
|
||||
if (`/usr/bin/id -u` == 0) then
|
||||
set prompt="`hostname -s`# "
|
||||
else
|
||||
set prompt="`hostname -s`% "
|
||||
endif
|
||||
endif
|
||||
|
||||
umask 022
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user