378 Commits

Author SHA1 Message Date
ef3427454e extend to 64 cores for AMD SMP systems
Change-Id: Ifa96ecaa60e3e9d5679d7d89af4a9148603d07cf
2015-10-01 14:22:44 +02:00
b0eaaeda2b Fix Statistical Profiling support
Change-Id: I5ebed6ead53e2f696d53d6d72e6e370e6e127820
2015-10-01 14:22:44 +02:00
b7d7e202a9 SMP: allow compilation with clang
Change-Id: Iec57820d150f2436cb3b7c543f662d3313197a4c
2015-10-01 14:22:43 +02:00
David van Moolenbroek
b7f0178aeb Import NetBSD time(1)
Change-Id: I035d21a926aa82434c24a84b914bd58ac064e66a
2015-09-29 18:16:14 +00:00
David van Moolenbroek
d1e4d7ce7d Import NetBSD csh(1)
Jobctl warning commented out.  Largely untested.

Change-Id: I4dffe23a2855a374628c820703b51591633aed64
2015-09-29 18:15:52 +00:00
David van Moolenbroek
29346ab043 PM: add support for wait4(2)
This patch adds support for the wait4 system call, and with that the
wait3 call as well.  The implementation is absolutely minimal: only
user and system times of the exited child are returned (with all other
rusage fields left zero), and there is no support for tracers.  Still,
this should cover the main use cases of wait4.

Change-Id: I7a04589a8423a23990ab39aa38e85d535556743a
2015-09-29 18:15:28 +00:00
David van Moolenbroek
bc2d75fa05 Rework getrusage(2) infrastructure
- the userland call is now made to PM only, and PM relays the call to
  other servers as appropriate; this is an ABI change that will
  ultimately allow us to add proper support for wait3() and the like;
  for the moment there is backward compatibility;
- the getrusage-specific kernel subcall has been removed, as it
  provided only redundant functionality, and did not provide the means
  to be extended correctly in the future - namely, allowing the kernel
  to return different values depending on whether resource usage of
  the caller (self) or its children was requested;
- VM is now told whether resource usage of the caller (self) or its
  children is requested, and it refrains from filling in wrong values
  for information it does not have;
- VM now uses the correct unit for the ru_maxrss values;
- VFS is cut out of the loop entirely, since it does not provide any
  values at the moment; a comment explains how it should be readded.

Change-Id: I27b0f488437dec3d8e784721c67b03f2f853120f
2015-09-28 14:06:59 +00:00
David van Moolenbroek
0f8e20a12c getrusage(2): zero out ru_nsignals field
The current value was both wrong (counting spawned kernel signals
rather than delivered user signals) and returned for the calling
process even if the request was for the process's children.
For now we are better off not populating this field at all.

Change-Id: I6c660be266b5746b7c3db57ae88fa7f872961ee2
2015-09-28 14:06:58 +00:00
David van Moolenbroek
cd27b2627a getrusage(2): zero out ru_i[xds]rss fields
The current values were both inaccurate (especially for dynamically
linked executables) and using the wrong unit (bytes, instead of
kilobytes times ticks-of-execution).  For now we are better off not
populating these fields at all.

Change-Id: I195a8fa8db909e64a833eec25f59c9ee0b89bdc5
2015-09-28 14:06:58 +00:00
David van Moolenbroek
0f5c95a00b PM: make child time accumulation POSIX compliant
POSIX states that times() and getrusage() should only return child
user and system times of terminated children for which wait*() has
returned their PIDs.

Change-Id: I38e19ad71543a3b91e944bef8e4e1bd903de51bf
2015-09-28 14:06:57 +00:00
David van Moolenbroek
b80da2a01d commands: move manpages into command directories
Change-Id: Icf8a2d26629a1822725022c9ee21c587d3c4c3b4
2015-09-28 14:06:06 +00:00
81b1f87117 Fix noassert builds
Change-Id: I5626950ffa29afe7a0fb9e9144839b311824da92
2015-09-25 15:47:43 -07:00
David van Moolenbroek
ba736c7968 libpuffs: clean up, unbreak
- move MINIX3-specific files into minix/lib/libpuffs;
- resynchronize the remaining files with NetBSD code;
- remove a few unnecessary changes;
- put remaining MINIX3-specific changes in __minix blocks;
- sort out the source files being linked at all.

The result is that libpuffs now successfully links against FUSE
file system programs again.  It can successfully mount, perform
some of the most basic operations, and unmount the file system.

Change-Id: Ieac220f7ad8c4d1fa293abda81967e8045be0bb4
2015-09-23 12:05:03 +00:00
David van Moolenbroek
7c48de6cc4 Resolve more warnings
Change-Id: Ibc1b7f7cd45ad7295285e59c6ce55888266fece8
2015-09-23 12:04:58 +00:00
David van Moolenbroek
9488aa4c04 Import NetBSD flock(1)
Also fix the MINIX3 libc flock(3) implementation.

Change-Id: Ia80280029968786d7f029940ec02e942057701bd
2015-09-23 12:03:13 +00:00
David van Moolenbroek
875abb8724 swifi: various improvements
- no longer inject fewer faults than instructed;
- no longer apply a limit on the number of injected faults;
- refactory to allow for random faults (type 99);
- also allow for stop faults (type 50);
- massive dead code cleanup;
- move outdated test cruft into tests/ subdirectory; it is kept only
  as an example of how to use swifi.

Change-Id: I8a3cb71902dfaadb7bf785723b917307db83d0d5
2015-09-23 12:03:12 +00:00
David van Moolenbroek
32b187558b Deprivilege some network commands
At the very least, these can be used to test for the existence of
files not normally accessible by unprivileged users.

Change-Id: I054cf6d033a1604bbbc871db37103a67067abe84
2015-09-23 12:03:12 +00:00
David van Moolenbroek
d0055759dd commands: resolve compiler warnings
Change-Id: I95f0d0c48f998d4d950a0800eedd5fbbf2e50423
2015-09-23 12:03:11 +00:00
David van Moolenbroek
fd962fdd93 Retire decomp16(1)
Change-Id: I455aac47b3efa4ffa5cc8305c6760f92e1e8642a
2015-09-23 12:03:11 +00:00
David van Moolenbroek
c0d9ad695c Retire ci(1), co(1), svclog(1)
Change-Id: I1bd1d92b9aacd4dfc4843c423862ae540fe2b557
2015-09-23 12:03:10 +00:00
David van Moolenbroek
33513d60e9 fbdctl(8): move to proper location
- move from minix/commands to minix/usr.sbin;
- install into /usr/sbin instead of /usr/bin;
- move manual page into source directory;
- resolve compilation warning;
- convert to KNF.

Change-Id: I1206b52e8804a68a3a80f6d7f63916e7fcdc9e3f
2015-09-23 12:03:10 +00:00
David van Moolenbroek
c175cce5e6 diskctl(8): move to proper location
- move from minix/commands to minix/usr.sbin;
- install into /usr/sbin instead of /usr/bin;
- move manual page into source directory;
- resolve compilation warning;
- convert to KNF.

Change-Id: Iccb4a8b27ae220254bae19e9198478b40706f542
2015-09-23 12:03:09 +00:00
David van Moolenbroek
964427e0ea btrace(8): move to proper location
- move from minix/commands to minix/usr.sbin;
- install into /usr/sbin instead of /usr/bin;
- move manual page into source directory;
- resolve compilation warning;
- convert to KNF.

Change-Id: I08c16998bd499a468799a6587f6fe45f42590461
2015-09-23 12:03:09 +00:00
David van Moolenbroek
d8634bad6a Move OpenBSD diff(1) into minix/usr.bin
Editor's note: NetBSD uses GNU diff.

Change-Id: I15d4441c73e0c626d0e5fda8c8683d131fbcbc38
2015-09-23 12:03:08 +00:00
David van Moolenbroek
040ec64444 libfetch: switch to external/bsd version
Change-Id: I7eb6fbf0ae6c008e399fe9bffdfc2b98dfed3432
2015-09-23 12:03:08 +00:00
David van Moolenbroek
319e7a6d07 Update, move NetBSD find(1)
Change-Id: Iccda44465d49dba407d1ac1b1ced8aa8b4e6d8aa
2015-09-23 12:03:08 +00:00
David van Moolenbroek
e7ca52fbf9 Import NetBSD cmp
Change-Id: I0e7f6c69742db475ddba6a9159f167a53d151169
2015-09-23 12:03:07 +00:00
David van Moolenbroek
93d36fc9d8 Import NetBSD rcmd, rcp, rsh, rshd
Change-Id: I83d908bbe17f04826e9b5c3a220a5bb2c3a51c80
2015-09-23 12:03:06 +00:00
David van Moolenbroek
ed223591a8 libc: support for deprecated FIO* ioctl(2) calls
Various generic file IOCTL calls should be processed by VFS rather
than individual drivers.  For this reason, we rewrite them to use
fcntl(2) instead.

Change-Id: I38a5f3c7b21943a897114a51678a800f7e7f0a77
2015-09-23 12:03:06 +00:00
David van Moolenbroek
20054ae93f Kernel: separate userland ABI on kernel page
Currently, the userland ABI uses a single field ('user_sp') far
into the very large 'kinfo' structure on the shared kernel
information page.  This precludes us from modifying or getting
rid of 'kinfo' in the future without breaking userland.  This
patch adds a separate 'kuserinfo' structure to the kernel
information page, with only information that is part of the
userland ABI, in an extensible manner.  Userland now uses this
field if it is present, and falls back to the old field if not.

Change-Id: Ib7b24b53a440f40a2edc28cdfa48447ac2179288
2015-09-23 12:01:15 +00:00
David van Moolenbroek
26f5c8f84b Kernel: store ARM frclock info in one structure
This change serves to reduce the clutter inside the top-level kerninfo
structure, and allows other ARM-specific values to be added on the
kernel page in one place.

Change-Id: I36a6aada9dbd1230b25014728be675d389088667
2015-09-23 12:01:10 +00:00
David van Moolenbroek
d91f738bd8 Kernel: export clock information on kernel page
Please note that this information is for use by system services only!
The clock facility is not ready to be used directly by userland, and
thus, this kernel page extension is NOT part of the userland ABI.

For service programmers' convenience, change the prototype of the
getticks(3) to return the uptime clock value directly, since the call
can no longer fail.

Correct the sys_times(2) reply message to use the right field type
for the boot time.

Restructure the kernel internals a bit so as to have all the clock
stuff closer together.

Change-Id: Ifc050b7bd253aecbe46e3bd7d7cc75bd86e45555
2015-09-23 12:00:46 +00:00
David van Moolenbroek
594df55e53 Abstract away minix_kerninfo access
Instead of importing an external _minix_kerninfo variable, any code
using the shared kernel page should now call get_minix_kerninfo(3).
Since this is the only logical name for such a function, rename the
previous get_minix_kerninfo call to ipc_minix_kerninfo.

Change-Id: I2e424b6fb55aa55d3da850187f1f7a0b7cbbf910
2015-09-21 15:09:04 +00:00
David van Moolenbroek
e4d99eb9b0 Basic live rerandomization infrastructure
This commits adds a basic infrastructure to support Address Space
Randomization (ASR).  In a nutshell, using the already imported ASR
LLVM pass, multiple versions can be generated for the same system
service, each with a randomized, different address space layout.
Combined with the magic instrumentation for state transfer, a system
service can be live updated into another ASR-randomized version at
runtime, thus providing live rerandomization.

Since MINIX3 is not yet capable of running LLVM linker passes, the
ASR-randomized service binaries have to be pregenerated during
crosscompilation.  These pregenerated binaries can then be cycled
through at runtime.  This patch provides the basic proof-of-concept
infrastructure for both these parts.

In order to support pregeneration, the clientctl host script has
been extended with a "buildasr" command.  It is to be used after
building the entire system with bitcode and magic support, and will
produce a given number of ASR-randomized versions of all system
services.  These services are placed in /usr/service/asr in the
image that is generated as final step by the "buildasr" command.

In order to support runtime updating, a new update_asr(8) command
has been added to MINIX3.  This command attempts to live-update the
running system services into their next ASR-randomized versions.
For now, this command is not run automatically, and thus must be
invoked manually.

Technical notes:

- For various reasons, magic instrumentation is x86-only for now,
  and ASR functionality is therefore to be used on x86 only as well.
- The ASR-randomized binaries are placed in numbered subdirectories
  so as not to have to change their actual program names, which are
  assumed to be static in various places (system.conf, procfs).
- The root partition is typically too small to contain all the
  produced binaries, which is why we introduce /usr/service.  There
  is a symlink from /service/asr to /usr/service/asr for no other
  reason than to let userland continue to assume that all services
  are reachable through /service.
- The ASR count field (r_asr_count/ASRcount) maintained by RS is not
  used within RS in any way; it is only passed through procfs to
  userland in order to allow update_asr(8) to keep track of which
  version is currently loaded without having to maintain own state.
- Ideally, pre-instrumentation linking of a service would remove all
  its randomized versions.  Currently, the user is assumed not to
  perform ASR instrumentation and then recompile system services
  without performing ASR instrumentation again, as the randomized
  binaries included in the image would then be stale.  This aspect
  has to be improved later.
- Various other issues are flagged in the comments of the various
  parts of this patch.

Change-Id: I093ad57f31c18305591f64b2d491272288aa0937
2015-09-17 17:15:03 +00:00
David van Moolenbroek
fbbf2570b4 VM: hide harmless ACL warning for RS at startup
Change-Id: Ied8167bc44ffc336b4ab2478f11586b7d6ae0016
2015-09-17 17:14:58 +00:00
David van Moolenbroek
ef52a26bab VFS/libblockdriver: enlarge threads stacks for ASR
Change-Id: If4e858bc2dbb2c69850cd265ff612bd5a6119bd3
2015-09-17 17:14:53 +00:00
David van Moolenbroek
f55e3cae08 libmagic: fix ASR padding for memory mapping
The code could not decide whether to apply the padding to the start
or the end of the region, resulting in strange behavior because part
of the returned range might not have the right properties.  With this
patch, padding is now consistently applied at the end of the region,
since virtual mmap addresses are allocated from high to low.

Also fix a few small related bugs in error handling code.

Change-Id: I327814bb3921d7982ffc1296a5bf365d9c79c1d9
2015-09-17 17:14:47 +00:00
David van Moolenbroek
65c4b82f02 VM: align frame buffer
Lack of alignment causes minix_stack_fill to produce an incorrect
frame layout, subsequently resulting in a crash of the started
process.  For now, we assume that the other callers of
minix_stack_fill do get an aligned buffer through sbrk(3), but this
may have to be changed later as well.

Change-Id: I1575bd62b050749d1a1aae7417310c91713462c3
2015-09-17 17:14:38 +00:00
David van Moolenbroek
5ba2e6e6e8 VM/VFS: align ELF header buffer
The libexec ELF parser expects to be given a word-aligned buffer,
but the ASR pass may cause VM and VFS to pass it an arbitrarily
aligned buffer, causing libexec to refuse loading the executable.
This patch aligns the buffers explicitly.

Change-Id: Ic2d5fd3a8f204c3e4f000cffdb7ac71c8339257a
2015-09-17 17:14:29 +00:00
David van Moolenbroek
139ae0da30 ASR pass: disable caller padding by default
The feature is fundamentally broken.  See the comment in the code.

Change-Id: If36b06b0732cc4d18f20240ed96d30a7959b0d21
2015-09-17 17:14:20 +00:00
David van Moolenbroek
0b98e8aad8 Import ASR pass from llvm-apps
Change-Id: I106c5faf8d8f1af5d3f5542fe666532895413909
2015-09-17 17:14:09 +00:00
David van Moolenbroek
78ff1e69b6 libmagic: fail on all state transfer errors
Also do not report debugging information by default.

Change-Id: I5d80a3df3c3ecc16a577d88abe6e37a792add747
2015-09-17 17:14:03 +00:00
David van Moolenbroek
0d6c408f48 libblockdriver: suspend threads for live update
Same as for VFS.

Change-Id: I0f09d43f24c32361af5e5658923140c79244d3d1
2015-09-17 17:13:52 +00:00
David van Moolenbroek
728b0e5b34 VFS: suspend threads for live update
- do not allow live update for request and protocol free states if
  there are any worker threads that have pending or active work;
- destroy all worker threads before such live updates and recreate
  them afterwards, because transferring (the contents of) the
  thread stacks is not an option at this time;
- recreate worker threads in the new instance only if they were
  shut down before the state transfer, by letting RS provide the
  original preparation state as initialization information.

Change-Id: I846225f5b7281f19e69175485f2c88a4b4891dc2
2015-09-17 17:13:46 +00:00
David van Moolenbroek
129adfeb53 Annotations and tweaks for live update
This change is necessary for instrumentation-aided state transfer.

Change-Id: I24be938009f02e302a15083f9a7a11824975e42b
2015-09-17 17:13:38 +00:00
David van Moolenbroek
23369f9c9e DS: workaround for weak symbol issue
The bitcode file given to the instrumentation pass does not include
certain weak symbols, in particular regcomp and regfree, which are
required to be visible to the magic pass for state transfer to work
correctly.  This patch forces DS to make the calls using their actual
symbol names (with leading underscore), thus resolving the issue, but
this issue should really be solved in a cleaner and more generic way.

Change-Id: Iebee4341cc30ddabcf7593afb5c49d41c0839863
2015-09-17 17:13:28 +00:00
David van Moolenbroek
3a3478dcea magic pass: register additional compatible types
This patch is a first step towards working around the larger problem of
LLVM 3.x's use of bitcasting between structures and their elements to
deal with opaque types, replacing LLVM 2.x's actual unification.  The
patch allows the pass to register a larger number of compatible types,
in particular for structure pointers passed through function calls.
A skeleton is provided for dealing with structure elements as well, but
that part requires much more work.  It remains to be seen whether a
more structural approach to dealing with this problem may be warranted.

For now, this change is necessary to allow instrumented state transfer
of various "minix_timer" structures and pointers in PM and VFS.

Change-Id: Ib717d86ccfced53387e72a92750d22ae980c3466
2015-09-17 17:13:21 +00:00
David van Moolenbroek
ebef68bf4c libmagic: supply own ctype macros
Due to the current linker command line ordering, parts of lib(min)c
that are used exclusively by libmagic end up not being instrumented,
which then causes problems transferring pointers such as _ctype_tab_
and _tolower_tab_.  As a temporary workaround, we redefine the macros
that use those pointers.  A better long-term solution should
eventually render this patch obsolete.

Change-Id: Ice1d125ff6fb2f65ac6dcc6cf6eec7cd6176bee1
2015-09-17 17:13:13 +00:00
David van Moolenbroek
c8f6986185 libmagic: ignore kernel pointers on MINIX3
Change-Id: I8830cab3d6637bae6141dc2b0e209d319703787f
2015-09-17 17:13:03 +00:00
David van Moolenbroek
1aad172900 Make more services use stateful live update
Change-Id: If2e5b8e56fef633e471ec1cbb6e08ce3496ea755
2015-09-17 17:12:02 +00:00
David van Moolenbroek
a4220d7774 tests: extend multicomponent live update test
- test multicomponent live update with and without rs and/or vm;
- retry the update a few times if the failure code suggests it might
  be a transient failure.

Change-Id: I5fce256bb418be257353ed21428f672d851d974d
2015-09-17 14:11:48 +00:00
David van Moolenbroek
b6b6793d05 tests: improve testrelpol.sh robustness
- fix a TOCTOU bug;
- stop the script on permanent failure.

Change-Id: I570cce3427945ad34d283ded013219c93402ddf9
2015-09-17 14:11:09 +00:00
David van Moolenbroek
54434d4eff tests: remove VM exceptions from testrelpol.sh
Change-Id: Ied1db7e77d1849ecb5e92fe9694bb395983c6122
2015-09-17 14:10:53 +00:00
David van Moolenbroek
c0df94ec22 RS: remove support for unsafe updates
This feature should no longer be necessary.

Change-Id: I9bff628be020cf1741bffaeb3bb97e3660a54aea
2015-09-17 14:09:47 +00:00
David van Moolenbroek
4506a0eebf VM: allocate cache pages in mmap region
That way, these pages are transferred during live update, as they
should.  This resolves a mfs crash after a number of live updates.

Change-Id: Ia53bec2692b2114c29b96a453beb0f915f56453a
2015-09-17 14:09:06 +00:00
David van Moolenbroek
7f79fb8810 Improve asynsend support for process swapping
This resolves various system stalls while running testrelpol.

Change-Id: Ie70fc2dbcdb0a8c9e3800cc0df564be747e111ec
2015-09-17 14:08:30 +00:00
David van Moolenbroek
5105ab554b Ignore a new ARM driver entry for instrumentation
Change-Id: I710a7534d2ba41107641252b9f80f197d04ba107
2015-09-17 14:08:01 +00:00
David van Moolenbroek
c07c198b5f Disable malloc instrumentation for VM (#2)
When the malloc code is instrumented, the global _brksize variable
should not be transferred.  However, when the malloc code is not
instrumented, failing to transfer _brksize would reset the heap
upon state transfer.  In this patch, the magic pass stores the flag
indicating whether memory function instrumentation is disabled, in
the target process.  This allows libmagic to check this flag during
state transfer, to see whether it should transfer _brksize or not.

Change-Id: Ia004651e21e08b0ed3f5305865c53c6659e18f38
2015-09-17 14:07:31 +00:00
David van Moolenbroek
76b68f9f99 Disable malloc instrumentation for VM (#1)
This patch changes the VM makefile to specify that the magic pass is
to skip memory function instrumentation, and to transfer the data
variables of the malloc code (thus overriding the exception we made
for all other system services).  We add two magic pass flags to
achieve this.  Since the magic pass is a big bowl of spaghetti code,
ignoring whitespace changes while viewing this patch is recommended.

Change-Id: I5ab83b23d8437b37c44dea99537bc202469c9df6
2015-09-17 14:05:14 +00:00
David van Moolenbroek
b7725c8552 Fix mmap leak in malloc code upon state transfer
The NetBSD libc malloc implementation uses a memory-mapped area for
its page directory.  Since the process heap is reconstructed upon
state transfer for live update, this memory-mapped area must not be
transferred to the new process.  However, as the new instance of the
process being updated inherits all memory-mapped areas of the old
instance, it also automatically inherits the malloc implementation's
page directory.  Thus, we must explicitly free this area in order to
avoid a memory leak.

The magic pass already detects (de)allocation functions called from
within other (de)allocation functions, which is why the mmap(2) and
munmap(2) calls of the malloc code are not instrumented as it is.
This patch changes that particular case to allow a different hook
function to be called for such "nested" allocation calls, for a
particular set of nested calls.  In particular, the malloc(3) code's
mmap(2) and munmap(2) calls are replaced with magic_nested_mmap and
magic_nested_munmap calls, respectively.  The magic library then
tracks memory mapping allocations of the malloc code by providing an
implementation for these two wrappers, and frees the allocations upon
state transfer.

This approach was chosen over various alternatives:

- While it appears that nesting could be established by setting a
  flag while the malloc(3) wrapper is active, and testing the flag in
  the mmap(2)/munmap(2) wrappers, this approach would fail to detect
  memory-mapped allocations made from uninstrumented malloc(3) calls,
  and therefore not a viable option.
- It would be possible to obtain the value of the variables that
  store the information about the memory-mapped area in the malloc
  code.  However, this is rather difficult in practice due to the way
  the libc malloc implementation stores the size of the are, and it
  would make the solution more dependent on the specific libc malloc
  implementation.
- It would be possible to use the special "nested" instrumentation
  for allocations made from certain marked sections.  Since we mark
  the data section of the malloc code already, this would not be hard
  to do.  Switching to this alternative would change very little, and
  if for any reason this approach yields more advantages in the
  future, we can still choose to do so.

Change-Id: Id977405da86a72458dd10f18e076d8460fd2fb75
2015-09-17 14:04:43 +00:00
David van Moolenbroek
9b9bea921f Do not instrument malloc implementation variables
Since the heap is reconstructed upon state transfer, the old malloc
state is discarded.  In order to avoid state transfer errors, we can
and in fact must discard the internal state of the malloc
implementation.  This patch achieves this by using the sectionify
pass to mark the variables in the libminc malloc object as state that
must be skipped during state transfer.

Change-Id: Ie330f582c8bd45f37a878ea41fa0f9d4a18045e1
2015-09-17 14:03:47 +00:00
David van Moolenbroek
abf8a7e7b3 RS/VM: proper preparation for multi-VM live update
Due to changed VM internals, more elaborate preparation is required
before a live update with multiple components including VM can take
place.  This patch adds the essential preparation infrastructure to
VM and adapts RS to make use of it.  As a side effect, it is no
longer necessary to supply RS as the last component (if at all)
during the set-up of a multicomponent live update operation.

Change-Id: If069fd3f93f96f9d5433998e4615f861465ef448
2015-09-17 14:01:06 +00:00
David van Moolenbroek
5a4672e300 VM: undo actions after live-update rollback
During live update, the new instance of VM may make changes that,
after a rollback, have to be undone by the old instance of VM, in
particular because both instances share (read-write) all dynamically
allocated pages.

Change-Id: I2bcfa8e627ca6084b1991e0af7cccecc683894a2
2015-09-17 14:00:32 +00:00
David van Moolenbroek
40aba308a0 libmagic: free actual dsentry rather than a copy
This resolves an infinite loop during boot, in libblockdriver freeing
DMA memory at the end of a partition(3) call.

Change-Id: I0757aa48f769ea79eab7160f23ee4c97cf58e055
2015-09-17 14:00:07 +00:00
David van Moolenbroek
949a3e52e5 Break loose from llvm-apps entirely
Change-Id: I532f5f44c785c1a72407b504568d54fc6cbabf8f
2015-09-17 13:58:57 +00:00
David van Moolenbroek
0acd3f1ae0 Import magic library from llvm-apps
Change-Id: Icfbcfae6afc731a23e71448a7a5d0045b2c219e5
2015-09-17 13:58:32 +00:00
David van Moolenbroek
3e457fe321 Import magic pass from llvm-apps
Change-Id: I19535b913b50f2ff24aeb80ddefc92e305c31fe8
2015-09-17 13:57:53 +00:00
David van Moolenbroek
b5e2faaaaf Import sectionify pass from llvm-apps
Change-Id: I3e3ac102b4898ca22ed1d9c25ec309d77bbe32de
2015-09-17 13:57:29 +00:00
David van Moolenbroek
3956ee9eed LLVM passes: centralize Makefile structure
Make the passes we have so far, hello and WeakAliasModuleOverride,
use settings from a Makefile include file in the parent directory.
This change is in preparation of adding other passes.

Change-Id: Ib195ee7f5c7626f4975368b02c944382e87e3814
2015-09-17 13:56:41 +00:00
Erik van der Kouwe
63a89582ab x86_hdimage: increase image size for bitcode build
Make disk image size sufficient for LLVM bitcode build with symbols.

Edited by David van Moolenbroek to do this only when -b is given.

Change-Id: I3bde164756c477b4af5ed9435ca03da3b186cf7e
2015-09-17 13:55:38 +00:00
44bb91d464 BitCode: Fix Dynamic Binaries
Change-Id: I7f3b775426a0c79969c7efc7a9970683b9dd950c
2015-09-17 13:55:06 +00:00
3ceafe99fd Support BUILDVARS from cmd line in configure.llvm
Change-Id: I59527c60cb34c12fd2bed449b37bb812a83c4e42
2015-09-17 13:53:18 +00:00
Cristiano Giuffrida
035cdb2e79 llvm: Never rebuild gold in configure.llvm.
Change-Id: I7378ca38a5a9bf018823b6431d1a4ca8fbb10b58
2015-09-17 13:52:35 +00:00
Cristiano Giuffrida
c9590fa23a llvm: Fix OPTFLAGS.
Change-Id: Id35ac2821ad69825735c50a32bdd04d8453edb22
2015-09-17 13:52:24 +00:00
d8d3052dd0 QEMU default command lines updates
- Fix a bug in clientctl which tried to test for kvm. This simply
   remove this faulty test  as the kvm command has been deprecated by the
   QEMU project for a couple of years now.

 - Specify by default 256M of RAM as this is the minimal amount required
   for the whole-OS live update test to succeed.

 - Update the default command printed out at the end of the x86_hdimage
   script to be more generic, less focused on one use-case.

Change-Id: Ic555d50a3a1471f7d35cc7fd369f2292add6ac39
2015-09-17 13:51:14 +00:00
Cristiano Giuffrida
f8ddf7c81d releasetools: Fix CREATE_IMAGE_ONLY in x86 hdimage script.
Change-Id: Ie1c8dbedc16b8edac16f5b76b36df30b3a4eddb1
2015-09-17 13:51:02 +00:00
Cristiano Giuffrida
1e7bfb997f llvm: Build scripts improvements.
Change-Id: I278cdebccdba18be7e264bfd240ff02d4480b33c
2015-09-17 13:49:25 +00:00
Cristiano Giuffrida
04c5ac3eb5 llvm: Extend clientctl with many features.
Change-Id: I739eefa46458e956cb79c42a8cbf880428eec794
2015-09-17 13:49:03 +00:00
Cristiano Giuffrida
c3041d5c6d llvm: Fix module map generation.
Change-Id: If9c2bef4c0ef3d002ac65a2c66aabcf0cf99ff95
2015-09-17 13:48:40 +00:00
Cristiano Giuffrida
326b9df3db llvm: Improve error handling in configure.llvm.
Change-Id: I9aa8f8a07a512f642447c70dca2e85d40ebe2b2a
2015-09-17 13:48:18 +00:00
David van Moolenbroek
3779ed93c3 Kernel: IPC filter support for VM memory requests
The filtering also exposed the risk that a process be killed or
swapped while on the list of VM memory requests.  These cases are
now handled properly as well.

Change-Id: Ibd3897b34abdf33bce19d37b8e5f65fbd0fd9316
2015-09-17 13:46:23 +00:00
8b0f8559ee VM: set recovery policy to restart
- Update proc to select restart policy for VM
 - Update testrelpol to test the supported modes of recovery for VM
 - Small code cleanups in testrelpol as well.

Change-Id: I6958e100865c2429b9435f3f7cc7d018046378c3
2015-09-17 13:45:43 +00:00
David van Moolenbroek
95cb93971a VM: fix mmap region transfer range bug
A missing check to see whether the range being transferred is sane
(with a starting address lower than an ending address) caused extra
memory to be marked erroneously as copy-on-write for some processes,
ultimately resulting in pagefaults on the stack during live update
rollback.

Change-Id: I1516b509b485379606d8df05b8a0f514896a0f19
2015-09-17 13:44:55 +00:00
Dirk Vogt
a6db4d0a62 VM: live update - check for regions above stack
If the stack is not mapped at the VM_DATATOP (e.g. booted with
ac_layout = 1), there might be some more regions hiding above
the stack.  We also have to transfer those.

Change-Id: Idf3b94a36fcec8a10ace2f6dffe816faf0a88f60
2015-09-17 13:44:30 +00:00
Ben Gras
8f4f859b35 RS: synchronize priv from kernel after swap
. make sure the priv id etc is maintained so
	  future privctl talk about the right thing
	. solves broken IPC after update

Change-Id: I17ed0212c22d634e6db1e80f8dcb2fb8bffe82c6
2015-09-17 13:43:49 +00:00
David van Moolenbroek
2867e60add SEF: query VM about holes during state transfer
The 'memory' service has holes in its data section, which causes
problems during state transfer.  Since VM cannot handle page faults
during a multicomponent-with-VM live update, the state transfer must
ensure that no page faults occur during copying.  Therefore, we now
query VM about the regions to copy, thus skipping holes.  While the
solution is not ideal, it is sufficiently generic that it can be used
for the data section state transfer of all processes, and possibly
for state transfer of other regions in the future as well.

Change-Id: I2a71383a18643ebd36956c396fbd22c8fd137202
2015-09-17 13:43:06 +00:00
Ben Gras
683f1fcab3 vm: restartability improvements (#2)
also allocate vm pagetables dynamic-only.

further improves restart survivability.

Change-Id: Iac44845d9bd434408b23755274fa890a7b851373
2015-09-17 13:42:18 +00:00
Ben Gras
10e6ba68d2 vm: restartability improvements (#1)
Two bugs fixed wrt vm restartability.

	. make sure pagetable data is only allocated
	  using dynamic data instead of static spare pages
	  (bootstrap pages). They are needed for bootstrap
	  but now repeat some of the initialization so only
	  dynamic data remains. This solves the problem of
	  physical addresses changing (as static pages are
	  re-allocated for the new instance) after update.
	. pt_ptalloc has to be specified in bytes instead of
	  pde slot numbers. leaving pt_pt NULL causes mapping
	  transfers to fail because NULL happens to be mapped in
	  then and updates then happen there.
	. added some sanity checks against the above happening.

The new state is that VM can update many times, but the system
isn't fully reliable afterwards yet.

Change-Id: I7313602c740cdae8590589132291116ed921aed7
2015-09-17 13:41:26 +00:00
Ben Gras
8bab0dfa2a Kernel: delivermsg improvements
. make arch-independent, and local to proc.c, reduce code duplication
    . make vm_suspend public but unduplicated in proc.c
    . ask VM for handling once, 2nd time SIGSEGV process
    . remove debug printfs
    . test case for bogus sendrec() address argument

Change-Id: I3893758910c01de60b8fe3e50edd594296a0b73e
2015-09-17 13:41:09 +00:00
Cristiano Giuffrida
36f477c20e vm: Allow in-band metadata for cache blocks
Allow extra space for in-band metadata when allocating cache blocks.

Edited by David van Moolenbroek: since this effectively halves the
potential size of the typical file system cache, do this only when
compiling with instrumentation.

Change-Id: I0840af6420899ede2d5bb7539e79c0a456b5128d
2015-09-17 13:40:39 +00:00
Cristiano Giuffrida
75206e2f3e libmthread: Fix guard page mapping.
Edited by David van Moolenbroek to deallocate the guard page as well.
Note that while the new approach is better in theory (previously, the
hole could end up being filled by another allocated page), guard page
protection is now broken in practice, because VM does not support
setting specific page permissions (in this case, PROT_NONE).

Change-Id: I882624f5d152d3ebe82fca649cbad85aa4931780
2015-09-17 13:38:44 +00:00
0485087c58 testrelpol: let test specific services
If arguments are provided, the services list to test is set from those,
instead of initializing it with every currently running service.

If such arguments are present, also skip LiveUpdate tests.

Change-Id: I14f874666a610072a5ff4a60516e59cf04dc9e31
2015-09-17 13:37:55 +00:00
Cristiano Giuffrida
0c474453d1 tests: Expand the reliability test suite.
Change-Id: Ic7f90f2d4edae1f72f98b34bda70891330c27941
2015-09-17 13:37:40 +00:00
Cristiano Giuffrida
43065aa378 sef: Support for LLVM ltckpt instrumentation.
Change-Id: I86073bddc3a820ab3d7c5d016ea1348840b0260a
2015-09-17 13:36:35 +00:00
Cristiano Giuffrida
3f82ac6a4e services: Selectively enable stateful restart.
Change-Id: Ibf6afa3041013ca714e28b673abb1329cd72d2d5
2015-09-17 13:36:01 +00:00
Cristiano Giuffrida
dc76d7e9da rs: Update recovery policies for sched and mfs.
Edited by David van Moolenbroek.

Change-Id: I7bbe543e2349dca3856a17abddc8366d1f19fe10
2015-09-17 13:34:59 +00:00
Cristiano Giuffrida
3837bb5c0b rs: Add support for RS_FI.
Change-Id: Id8663859accfc4e3587db35dec7000059860fd49
2015-09-17 13:29:47 +00:00
Cristiano Giuffrida
eacaa8290b vm: Fix heap preallocation.
Change-Id: I5b7f6473b9bbff69eae6ab26c889ad8ed902ff3a
2015-09-17 13:28:17 +00:00
Cristiano Giuffrida
0be084004f vm: Fix vm cloning.
Change-Id: I996410ab1b9628cde797d9e5dd73ed07f13a884b
2015-09-17 13:27:24 +00:00
David van Moolenbroek
37489f8a24 Resolve boot-time VM/RS deadlock
VM used to call sendrec to send a boot-time RS_INIT reply to RS, but
RS could run into a pagefault at the same time, thus spawning a
message to VM, resulting in a deadlock.  We resolve this situation by
making VM acknowledge RS_INIT asynchronously at boot time, while
retaining the synchronous sendrec for subsequent RS_INIT responses.

Change-Id: I3cb72d7f8d6b9bfdc59a85958ada739c37fa3bde
2015-09-17 13:27:05 +00:00
Cristiano Giuffrida
0e78c0166c Switch to stateful restart.
The following services have been updated to support stateful restarts:
 - Drivers: tty
 - Filesystems: isofs, mfs, pfs, libvtreefs-based file servers
 - System servers: tty, ds, pm, vfs, vm

Change-Id: Ie84baa3ba1774047b3ae519808fe4116928edabb
2015-09-17 13:26:22 +00:00
Cristiano Giuffrida
2b641b28b1 ds: Add live update extensions.
Change-Id: I093c462ddad4a5e9b3dc39140f45f0e25e83bb55
2015-09-17 13:26:09 +00:00
Cristiano Giuffrida
50b7f13f9f Add live update-friendly annotations.
Change-Id: I7d7d79893836a20799ca548a350f3288e92581f0
2015-09-17 13:25:38 +00:00
Cristiano Giuffrida
5c8eb53d49 libsys: mark regions allocated for DMA as special
This ensures that they will not be relocated.

Edited by David van Moolenbroek.

Change-Id: Ic2a97bc65b94dfcf364c06577aa340a9a5299e74
2015-09-16 15:31:55 +00:00
Cristiano Giuffrida
162b8995bb vm: Let SEF know about special mmapped regions.
Change-Id: I742529a6747ddd181937aa1a45264b87677c01c8
2015-09-16 15:31:40 +00:00
David van Moolenbroek
e3f3566e33 RS: clean up dead services during shutdown
Previously, RS would clean up dead services only when it is idle.
During shutdown, all services are marked with the 'exiting' flag,
and these flags lead RS to conclude it is not idle.  Therefore, at
shutdown time, no services were cleaned up anymore, leading to
deadlock situations.  For example, VFS could end up waiting for a
service that was already dead, or one driver could end up waiting
for an interrupt on a line shared with another dead driver.

While it may be possible to ignore RS_EXITING when checking idle
status, other flags may have the same ultimate effect.  Therefore,
this patch skips the idle check altogether when in shutdown mode.

Change-Id: I071fa9545da1d43c5e5c2e0bc2b6c173e3bb57c3
2015-09-16 15:31:29 +00:00
David van Moolenbroek
1aa4eb6a85 RS: reset heartbeat status after rollback
While in a multicomponent live update that includes RS, the new RS
instance may receive heartbeat replies which, after a rollback, the
old RS instance will then never see.  As a result, the rolled-back
RS instance may end up killing well-behaving services.

Change-Id: I0f0af283c33502d5d55b27e353b62aec2e301285
2015-09-16 15:31:19 +00:00
David van Moolenbroek
f16b761d2a RS: use IPC filters to do a timed receive
Change-Id: I28df9920d8a65b47f3cf974ed9c5eb3174479d8a
2015-09-16 15:31:10 +00:00
Cristiano Giuffrida
fb6bd596bf rs: New RS.
Change-Id: I46e335d5dac49104028d7cb0706b3e85de752bfe
2015-09-16 15:30:48 +00:00
Cristiano Giuffrida
d196e2c333 sef: Extensions for new RS.
Change-Id: I89b6f8015b1f9c46bf98694450bdaa80b7777940
2015-09-16 15:30:34 +00:00
Cristiano Giuffrida
006d6e94f9 sef: New definitions and event loop refactory.
Change-Id: I0cd0906e513b2b804b94eebc86c76b5c402b572b
2015-09-16 15:30:24 +00:00
Cristiano Giuffrida
d40f735640 service: Extensions for new RS.
Change-Id: Ifb72c7e8c912709edce0fb9ba9efb570901be5fb
2015-09-16 11:22:14 +00:00
Cristiano Giuffrida
ac03aa4f32 include: Header file changes for new RS.
Change-Id: I33602adb6a8c42050fc5ee6dbdf6ee6a7aeabaab
2015-09-16 11:21:28 +00:00
Cristiano Giuffrida
e6f5b0cc65 sef: Naming refactory.
Change-Id: Id313e73fde577e48a17f2c16c808c9156a1be804
2015-09-16 11:07:18 +00:00
Cristiano Giuffrida
dd09614042 sef: GCOV cleanup.
Change-Id: I2e5a6ae10f45108a2c112f78e5a0af4f93e0bed1
2015-09-16 11:07:01 +00:00
Cristiano Giuffrida
65b4b95259 vm: Allow VM to make self calls when needed.
Change-Id: I7aada24adad3dc6bfe5b0bd4a50b5005c79ff887
2015-09-16 11:06:51 +00:00
Cristiano Giuffrida
63483e02e6 vm: Improve live update support.
Change-Id: I02da3ea32cd05c4ed84a6e199236e5df6e25cb60
2015-09-16 11:06:41 +00:00
Cristiano Giuffrida
53398d733f vm: Separate mmap regions.
Add support for compact address layout.  This feature can be enabled
through the ac_layout=1 boot option.

Change-Id: Ie20b808fce32b5c54d0a7e7210e0084a540e9613
2015-09-16 11:06:17 +00:00
Cristiano Giuffrida
48f446ecd5 vm: Extend the vm_memctl() interface.
Change-Id: I87b7c188bd1fc54a3ec943e7ff1d05c6f4c8a56a
2015-09-16 11:04:09 +00:00
Cristiano Giuffrida
7f439d4656 rs: Ditch dead code to munmap zero pages.
Change-Id: Ib184839e3b607986716fc48aec5ebd8ee796a065
2015-09-16 11:03:52 +00:00
Cristiano Giuffrida
704033fd9d libsys: Increase number of static grants.
This is required by the state transfer framework.

Change-Id: I6bc08cee6c70ff406fbd8d45a12721a26c86d45a
2015-09-16 11:03:42 +00:00
Cristiano Giuffrida
d639cffec9 libsys: Support for senda_reload().
Change-Id: I67f94515d2b89199643195d32d92f1bef9770359
2015-09-16 11:03:30 +00:00
Cristiano Giuffrida
e1f889d228 libsys: Change SEF Live Update state callback API.
The following callbacks are concerned:
 - state_save
 - state_isvalid

Change-Id: I75f71fe162ccd8b23b18cae15f844b79b290a8c1
2015-09-16 11:03:17 +00:00
Cristiano Giuffrida
01c875ce91 kernel: Debug printing at live update time.
Change-Id: I0fa896eb248b3b62e1858f76196d3d6862a30f2b
2015-09-16 11:03:04 +00:00
Cristiano Giuffrida
062400c0e2 kernel: Handle IPC properly at live update time.
Change-Id: I2dfc6c6cf4d2bfe198e159d3e4b7c50d0bb499c8
2015-09-16 11:02:53 +00:00
Cristiano Giuffrida
56e56d2af2 kernel: Inherit allowed memory, IRQ & I/O ranges
Inherit at live update time all the priviledges previously acquired by
the process.

Change-Id: I1fd6ab16680ea85a1f3d8d1c106a7c716bf65e8e
2015-09-16 11:02:44 +00:00
Cristiano Giuffrida
9e6b1315c3 kernel: Allow kernel calls to return ENOTREADY.
This is required to avoid races with safecopy() at live update time.

Change-Id: I1f3e22d40f22d94bd2b850915f9b8163a08b5616
2015-09-16 11:02:31 +00:00
Cristiano Giuffrida
c8a9900b0c kernel: Add support for IPC filters.
Edited by David van Moolenbroek.

Change-Id: Ia0052c42a0f218d011dd2da1e3db6c5b2107adc7
2015-09-16 11:02:24 +00:00
Cristiano Giuffrida
6fc5006250 kernel: Add SYS_PRIV_CLEAR_IPC_REFS support.
Change-Id: Ie5e86191d5040f305a5a42942d83319cd600bfb6
2015-09-16 11:02:13 +00:00
Cristiano Giuffrida
a1760b573b kernel: Extend the {sys,vm}_update() interfaces.
Change-Id: I9ada3c04c08d219b198e9081f4e1942b11c722f6
2015-09-16 11:01:47 +00:00
Cristiano Giuffrida
76bf77a21f kernel: Extend the sys_whoami() interface.
Add support for init flags.

Change-Id: Ibb4d7eb9064d2bbee6d51112ad0c56b2750a5f8e
2015-09-16 11:01:36 +00:00
Cristiano Giuffrida
41022be182 kernel: Extend the sys_statectl() interface.
Change-Id: Ica37640f61513db9466dacf861a8148e3fb799d5
2015-09-16 11:01:15 +00:00
Cristiano Giuffrida
606626c691 include: Add sys flags definitions.
Change-Id: I8ecbe636641467efea058a9527416fc25d954daf
2015-09-16 10:59:34 +00:00
David van Moolenbroek
de95c84d3e VFS: fix short select(2) timeouts
Some select queries require a response from device drivers.  If a
select call is nonblocking (with a zero timeout), the response to
the caller may have to be deferred until all involved drivers have
responded to the initial query.  This is handled just fine.

However, if the select call has a timeout that is so short that it
triggers before all the involved drivers have responded, the
resulting alarm would be discarded, possibly resulting in the call
blocking forever.  This fix changes the alarm handler such that if
the alarm triggers too early, the select call is further handled
as though it was nonblocking.

This fix resolves a test77 deadlock on really slow systems.

Change-Id: Ib487c8fe436802c3e11c57355ae0c8480721f06e
2015-09-16 10:41:46 +00:00
David van Moolenbroek
fefec20e6b procfs: do not list init in /proc/services
It is not a system service.

Change-Id: Ibfbf08aa52095826c19172e517bcbd292e7944a0
2015-09-07 22:56:19 +00:00
David van Moolenbroek
d09f72c453 Kernel: improve stacktrace printing
- corrupt stack traces could trigger a kernel panic;
- output consistency and spelling.

Change-Id: I04c9ac7db77593d6e837a28c83f1734adc8d9da7
2015-09-07 22:56:00 +00:00
David van Moolenbroek
1d9856e713 inet: resolve some compile and runtime warnings
- ping(1) triggers warnings about unimplemented exceptions for select;
  even if there could be a useful implementation (which is doubtful),
  the warnings are not helping anyone right now;
- the clock_t data type has changed.

Change-Id: Ie5b1383e7657e8501f63bb4b9d255c6502567a15
2015-09-01 16:21:20 +00:00
David van Moolenbroek
4b12166f26 VFS: workaround to allow TIOCSCTTY on PTYs
Fix /dev/tty-related issues in tmux(1) by hardcoding the PTY major
in VFS in addition to the TTY major.  Even though this is exactly
what we did NOT want to have to do, the actual fix for this issue
is going to take a little longer.

Change-Id: I24c75eaf688b9ebd28e931f2e445b8442cfdac78
2015-09-01 11:42:03 +00:00
David van Moolenbroek
29e004d23b VFS: make message pointer management more robust
The previous approach of storing pointers to messages structures for
thread-blocking sendrec operations relied on several assumptions,
which if violated could lead to odd cases of memory corruption.
With this patch, VFS resets pointers right after use, avoiding that
any dangling pointers are accidentally dereferenced later.  This
approach was already used in some cases, but not all of them.

Change-Id: I752d994ea847b46228bd2ccf4e537deceb78fbaf
2015-08-31 12:58:39 +00:00
David van Moolenbroek
56ac45c10b VFS: check X bit, not R bit, opening executables
For dynamically linked executables, the interpreter is passed a
file descriptor of the binary being executed.  To this end, VFS
opens the target executable, but opening the file fails if it is
not readable, even when it is executable.  With this patch, when
opening the executable, it verifies the X bit rather than the R
bit on the file, thus allowing the execution of dynamically
linked binaries that are executable but not readable.

Add test86 to verify correctness.

Change-Id: If3514add6a33b33d52c05a0a627d757bff118d77
2015-08-31 12:55:55 +00:00
David van Moolenbroek
9f15e7b366 VFS: tweak coredump wrapper code
Change-Id: I6c1f50910d906b25f6df2b48f2cbfb899850924e
2015-08-31 12:55:48 +00:00
David van Moolenbroek
253dbfc285 VFS: resolve noassert warning
Change-Id: I647f5a7b3c2935be3df032873705be83de9aaffb
2015-08-31 12:55:43 +00:00
David van Moolenbroek
6c31058de4 sched: simplify
- do not use timers when there is only ever one timer;
- do not include kernel header files for no reason;
- do not reply to notifications ever.

Change-Id: I5817e22c1b46c4e30e5135069df318af0b4f87fd
2015-08-31 12:55:30 +00:00
David van Moolenbroek
736b88cf53 DS: fix regex memory leaks
The regcomp(3) calls had no matching regfree(3) calls.

Change-Id: I5250d62e6ab22821aff18bcdc336cb485df6868e
2015-08-31 12:55:18 +00:00
David van Moolenbroek
4472b590c7 libminixfs: rework prefetch API
This patch changes the prefetch API so that file systems must now
provide a set of block numbers, rather than a set of buffers.  The
result is a leaner and more well-defined API; linear computation of
the range of blocks to prefetch; duplicates no longer interfering
with the prefetch process; guaranteed inclusion of the block needed
next into the prefetch range; and, limits and policy decisions better
established by libminixfs now actually being moved into libminixfs.

Change-Id: I7e44daf2d2d164bc5e2f1473ad717f3ff0f0a77f
2015-08-14 18:39:30 +00:00
David van Moolenbroek
6c46a77d95 libminixfs: better support for read errors and EOF
- The lmfs_get_block*(3) API calls may now return an error.  The idea
  is to encourage a next generation of file system services to do a
  better job at dealing with block read errors than the MFS-derived
  implementations do.  These existing file systems have been changed
  to panic immediately upon getting a block read error, in order to
  let unchecked errors cause corruption.  Note that libbdev already
  retries failing I/O operations a few times first.

- The libminixfs block device I/O module (bio.c) now deals properly
  with end-of-file conditions on block devices.  Since a device or
  partition size may not be a multiple of the root file system's block
  size, support for partial block retrival has been added, with a new
  internal lmfs_get_partial_block(3) call.  A new test program,
  test85, tests the new handling of EOF conditions when reading,
  writing, and memory-mapping a block device.

Change-Id: I05e35b6b8851488328a2679da635ebba0c6d08ce
2015-08-14 18:39:26 +00:00
David van Moolenbroek
1311233cfb libminixfs: keep track of block usage
This patch changes the libminixfs API and implementation such that the
library is at all times aware of how many total and used blocks there
are in the file system.  This removes the last upcall of libminixfs
into file systems (fs_blockstats).  In the process, make this part of
the libminixfs API a little prettier and more robust.  Change file
systems accordingly.  Since this change only adds to MFS being unable
to deal with zones and blocks having different sizes, fail to mount
such file systems immediately rather than triggering an assert later.

Change-Id: I078e589c7e1be1fa691cf391bf5dfddd1baf2c86
2015-08-14 18:39:21 +00:00
David van Moolenbroek
0314acfb2d libminixfs: miscellaneous API cleanup
Mostly removal of unused parameters from calls.

Change-Id: I0eb7b568265d1669492d958e78b9e69d7cf6fc05
2015-08-14 18:39:00 +00:00
David van Moolenbroek
b8f6d4a649 libminixfs: do not flush blocks that are in use
This removes an implicit requirement for the way the libminixfs API is
to be used, namely that a block is to be marked as dirty only once its
contents have been fully updated, within a single get_block/put_block
window.  The requirement may not be appropriate for all file systems.

Change-Id: I6a129d51b1a5e9aec1572039dc7c1c82dd795db5
2015-08-13 13:46:52 +00:00
David van Moolenbroek
cb9453ca63 libminixfs: add support for peeking blocks
With this change, the lmfs_get_block*(3) functions allow the caller to
specify that it only wants the block if it is in the cache or the
secondary VM cache.  If the block is not found there, the functions
return NULL.  Previously, the PREFETCH method would be used to this
end instead, which was both abuse in name and less efficient.

Change-Id: Ieb5a15b67fa25d2008a8eeef9d126ac908fc2395
2015-08-13 13:46:50 +00:00
David van Moolenbroek
d75faf18d9 libminixfs: add support for memory-mapped holes
When VM asks a file system to provide a block to satisfy a page fault
on a file memory mapping, the file system previously had no way to
inform VM that the block is a hole, since there is no corresponding
block on the underlying device.  To work around this, MFS and ext2
would actually allocate a block for the hole when asked by VM, which
not only defeats the point of holes in the first place, but also does
not work on read-only file systems.  With this patch, a new libminixfs
call allows the file system to inform VM about holes.  This issue does
raise the question as to whether the VM cache is using the right data
structures, since there are now two places where we have to fake a
device offset.  This will have to be revisited in the future.

The patch changes file systems accordingly, and adds a test to test74.

Change-Id: Ib537d56b3f30a8eb05bc1f63c92b5c7428d18f4c
2015-08-13 13:46:48 +00:00
David van Moolenbroek
e94f856b38 libminixfs/VM: fix memory-mapped file corruption
This patch employs one solution to resolve two independent but related
issues.  Both issues are the result of one fundamental aspect of the
way VM's memory mapping works: VM uses its cache to map in blocks for
memory-mapped file regions, and for blocks already in the VM cache, VM
does not go to the file system before mapping them in.  To preserve
consistency between the FS and VM caches, VM relies on being informed
about all updates to file contents through the block cache.  The two
issues are both the result of VM not being properly informed about
such updates:

 1. Once a file system provides libminixfs with an inode association
    (inode number + inode offset) for a disk block, this association
    is not broken until a new inode association is provided for it.
    If a block is freed and reallocated as a metadata (non-inode)
    block, its old association is maintained, and may be supplied to
    VM's secondary cache.  Due to reuse of inodes, it is possible
    that the same inode association becomes valid for an actual file
    block again.  In that case, when that new file is memory-mapped,
    under certain circumstances, VM may end up using the metadata
    block to satisfy a page fault on the file, due to the stale inode
    association.  The result is a corrupted memory mapping, with the
    application seeing data other than the current file contents
    mapped in at the file block.

 2. When a hole is created in a file, the underlying block is freed
    from the device, but VM is not informed of this update, and thus,
    if VM's cache contains the block with its previous inode
    association, this block will remain there.  As a result, if an
    application subsequently memory-maps the file, VM will map in the
    old block at the position of the hole, rather than an all-zeroes
    block.  Thus, again, the result is a corrupted memory mapping.

This patch resolves both issues by making the file system inform the
minixfs library about blocks being freed, so that libminixfs can
break the inode association for that block, both in its own cache and
in the VM cache.  Since libminixfs does not know whether VM has the
block in its cache or not, it makes a call to VM for each block being
freed.  Thus, this change introduces more calls to VM, but it solves
the correctness issues at hand; optimizations may be introduced
later.  On the upside, all freed blocks are now marked as clean,
which should result in fewer blocks being written back to the device,
and the blocks are removed from the caches entirely, which should
result in slightly better cache usage.

This patch is necessary but not sufficient to resolve the situation
with respect to memory mapping of file holes in general.  Therefore,
this patch extends test 74 with a (rather particular but effective)
test for the first issue, but not yet with a test for the second one.

This fixes #90.

Change-Id: Iad8b134d2f88a884f15d3fc303e463280749c467
2015-08-13 13:46:46 +00:00
David van Moolenbroek
b65ad59e08 libminixfs: add support for 64-bit block numbers
There are currently no devices out there that require this change.
The change is merely needed to support subsequent changes.

Change-Id: I64214c5f46ff4a2260815d15c15e4a17709b9036
2015-08-13 13:46:44 +00:00
David van Moolenbroek
bd851af48f VFS: merge scratchpad into fproc
There is no reason to keep these tightly coupled data structures
separate.  Moreover, there is no reason to have a union of file
descriptor and file pointer, since the second can be derived from
the first.  The result are somewhat cleaner VFS internals.

Change-Id: I854da7d8291177878eecfc3077ef0a9e0cc82aaa
2015-08-13 13:45:02 +00:00
David van Moolenbroek
162f54c289 service(8): no need to include kernel headers
Change-Id: I8fb7a1a58457909b7759a74925a12cf9b11261f0
2015-08-13 13:44:57 +00:00
David van Moolenbroek
e9cd054009 Restore and expand NONE_MAJOR comment
This fixes #50.

Change-Id: I318d08e8c57c12cfd409700b14c88a90c81a1715
2015-08-13 13:44:52 +00:00
David van Moolenbroek
a6fc634735 etc: create system log files
The new syslogd(8) does not create log files that do not already
exist, and thus, we adopt the NetBSD way of creating them.

Change-Id: Icd7fdba362726696df6a52dd55c049fd2bfcc2d3
2015-08-10 11:38:16 +00:00
David van Moolenbroek
ec725af4c5 lwip: no need to retrieve own endpoint
Change-Id: I86bd20be9b1aec4116edbe112eb562737860568f
2015-08-08 16:57:14 +00:00
David van Moolenbroek
efa7e3e6d2 Kernel: correctly set USE_ defines from Makefile
Without defining these to 1, #if statements on them will fail.

Change-Id: Ifc4824a6ffacc4bebcfd6f1110c864d7eb16401a
2015-08-08 16:56:37 +00:00
David van Moolenbroek
a082b2af62 libsys: add Tomas Hruby's asynsend barrier
This barrier ensures that all fields of an asynchronously sent
message are properly initialized before the message is marked as
valid.

Change-Id: I7b9590c11c4e040c8f992f1dd2581e54201bf214
2015-08-08 16:56:20 +00:00
David van Moolenbroek
3091b8cf26 Kernel: fix async message failure handling crash
If an asynchronous message is delivered during an ipc_receive(2) call,
but a failure occurred while copying out the status to the sending
process, then the receiving process would be left in an inconsistent
state, leading to a kernel crash shortly after.

For now, we fix this by altogether ignoring errors while copying out
the status field to the sending process.  While this resolves the
kernel crash, it is hardly ideal, since it will likely cause the same
message to be delivered repeatedly.  It would be better to disable
asynchronous communication from the sender process altogether, but this
solution requires more changes and thus more testing.

Change-Id: Ib00bf01ad29cdd10a5dee731d4788254d9037a76
2015-08-08 16:55:52 +00:00
David van Moolenbroek
e10ce184e4 libsys: make tickdelay(3) more reliable
Previously, there was a tiny chance that tickdelay(3) would return
early or that it would fail to reinstate a previous alarm.

- sys_setalarm(2) now returns TMR_NEVER instead of 0 for the time
  left if no previous alarm was set;
- sys_setalarm(2) now also returns the current time, to allow the
  caller to determine whether it got an alarm notification for the
  alarm it set or for a previous alarm that has just gone off;
- tickdelay(3) now makes use of these facilities.

Change-Id: Id4f8fe19a61ca8574f43131964e6f0317f613f49
2015-08-08 16:55:23 +00:00
David van Moolenbroek
8731fd1c47 audio: use standard Makefile structure
The previous approach of including libraries through the parent
directory's Makefile.inc created linking issues, with libchardriver
not finding snprintf in certain cases.  The new approach of including
libraries through the driver's only Makefile is the one used by all
other drivers.

Change-Id: I96e6308e12e54f0fce8ecf58bd061269860d4355
2015-08-08 16:55:03 +00:00
Kaustubh Kelkar
989398b447 Importing bin/domainname utility
Change-Id: Iaf2067296195d2d55b93d00ac593b431572ca4cd
2015-07-28 21:56:19 +00:00
David van Moolenbroek
ea69bfc71d tests: resolve new compiler warnings
Change-Id: I57f6602a9fe9e8524f7da4320b0d1a46889b90d6
2015-07-28 14:18:35 +00:00
Jean-Baptiste Boric
1facb0487c libc: add posix_spawn family of functions
The implementation is taken from newlib (BSD licensed) and test84 is based
on NetBSD's t_spawn.c

Change-Id: Ia4e9dd5204a0b4ef241a451978057e11fb29e3d6
2015-07-28 14:18:03 +00:00
Jacob Adams
7b2da7b2c7 update_bootcfg(8): Add actually useful information
Change-Id: I3f1aa2141827b3dc4072f2e8cedeecb40006e626
2015-07-28 10:03:50 +00:00
Jacob Adams
e01448dd84 Close #83 with fix suggested
Change-Id: I83975a0963d09eab73df62adf81ce8027ca41bb0
2015-07-28 09:58:12 +00:00
David van Moolenbroek
d8127f841f patch(1): fix arbitrary code execution bug
This is the combination of two NetBSD patches committed by Christos
Zoulas, based on the findings and Bitrig patch by Martin Natano.
The NetBSD log messages read:

  From Martin Natano @bitrig: Use execve(2) instead of system to
  apply patches that require rcs command execution instead system(3)
  to avoid malicious filenames in patches causing bad things to
  happen. In the process, lose SCCS support. It is not like we are
  shipping sccs commands for that to work.

And:

  Use absolute paths for RCS commands (Martin Natano)

Change-Id: Id44bd59a5a6bc6cd95d1e1fae468bd718cfff2db
2015-07-26 15:53:47 +00:00
Leonardo Fogel
4796287659 eMMC: add support to 8-bit mode.
Change-Id: I0470130eb5f8de319cd55c448a9aa1b9131e8e07
2015-07-26 15:53:37 +00:00
David van Moolenbroek
3e07920fe2 Import NetBSD syslogd(8)
The primary reason for the import is a likely GPL taint of the
original MINIX3 syslogd.  As a result, this import may still
have some rough edges.

Change-Id: I5c8d26eca10fc2dd50ecc9eab44a1d483cf068a9
2015-07-26 11:57:04 +00:00
David van Moolenbroek
818c405ae1 LOG: fix bugs in userland write handler
- report correct number of bytes written;
- correctly return partial writes on failure;
- do not overwrite result if there is a pending read.

Change-Id: I92aeeaee1eccb47c2aa2b6666a2f560c3cb17f42
2015-07-26 11:56:36 +00:00
David van Moolenbroek
0184c63535 libc: fix sysctl(3) error code
All unimplemented sysctl calls would return 2 instead of -1.

Change-Id: Ib486a03dc93969e646e4e11d890dc46855d790c4
2015-07-24 23:12:36 +00:00
Erik van der Kouwe
c97d4ff6e5 test83: add test to send strange/wrong UDP and TCP packets
Change-Id: I73444d2753adab140a4f8e6bee2db32282044888
2015-07-22 22:25:09 +02:00
Erik van der Kouwe
17fbdaf514 test82: share support functions in common.[ch] for test83
Change-Id: I3dfeacc3c2c143d3b696efa39a6f257d38281742
2015-07-22 22:24:22 +02:00
David van Moolenbroek
da32b6c32e orinoco: retire
This code is MPL-licensed and thus does not belong in the MINIX3
source tree.

Change-Id: I10388b05e90e83b95414cf9b469e50f49bc1db31
2015-07-20 16:55:15 +00:00
David van Moolenbroek
424cad2cd6 VFS: add support for F_DUPFD_CLOEXEC
Change-Id: Ibe422c6c99fe5fd1385884843ff9e15111810309
2015-07-20 13:55:10 +00:00
David van Moolenbroek
6d315cbf9e benchmarks: remove unixbench
This code appears to be GPL-licensed and thus does not belong in
the MINIX3 source tree.

Change-Id: I9e88c3ffd8eae8697b629899dba9728863a4413a
2015-07-20 11:05:28 +00:00
David van Moolenbroek
65b4a7fa8d mkfs.mfs: remove Linux mount check
This code is GPL-licensed and thus does not belong in the MINIX3
source tree.

Change-Id: Ie154f8a4b536df53b840e535283996b545f2bafc
2015-07-20 10:59:49 +00:00
David van Moolenbroek
4a1befb81d tests: remove IPC test set
This code appears to be GPL-licensed and thus does not belong in
the MINIX3 source tree.

Change-Id: I1d1060cd159322398284c6bb9716541819706e95
2015-07-19 17:58:10 +00:00
David van Moolenbroek
85fb986ba7 inet: fix state transitions in driver receipt code
This resolves a problem with ioctl(NIOCGETHSTAT) hanging forever
as identified by Erik van der Kouwe, and possibly many other corner
cases.

Change-Id: I2350c882dc6a0862e16454ec6b6c320d78780bcd
2015-07-17 18:44:39 +00:00
Erik van der Kouwe
86e41e22cf Add test82 (HTTP)
This test connects to a remote HTTP server to retrieve files, using various
chunk sizes and concurrency settings to exercise the network stack. The test
is only performed is USENETWORK=yes. This test requires the following URLs to
remain available: http://test82.minix3.org/test1.txt and
 http://test82.minix3.org/test2.bin. The former contains a 'Hello world'
message followed by a newline, the latter all 16-bit values in increasing
order, using big-endian notation.

Change-Id: I696106482fb1658f9657be2b6845a1b37a3d6172
2015-07-08 09:54:56 +02:00
Erik van der Kouwe
294d159017 Add new tests 80 (TCP) and 81 (UDP)
These new tests are largely based on the code from test 56 (UDS). Common code
is moved into a separate file common-socket.c. In some instances the tests
are too strict for TCP/UDP sockets, which may not always react instantly to
whatever happens on the other side (even locally). For these cases, the
ignore_* fields in struct socket_test_info indicate that there needs to be
an exception. There are also tests where it seems the functionality of inet
is either incorrect or incomplete with regard to the POSIX standard. In these
cases, the bug_* fields are used to document the issues while avoiding
failure of the test.

Change-Id: Ia860deb4559d42608790451936b1aade866faebc
2015-07-08 09:46:56 +02:00
Erik van der Kouwe
3e8d796eaa test48: skip some redundant combinations of parameters
Change-Id: I8ebecf4f61a99c653fd6dc0ae9510d5fd154dd4e
2015-07-08 09:32:17 +02:00
Erik van der Kouwe
3433559c50 test48: move can_use_network function to common code for reuse
Change-Id: I66a5f36f05fa4c4413b3b62c555fa58fbe5d73ea
2015-07-08 09:30:15 +02:00
Erik van der Kouwe
c4182e08ab tests: change u32_t to uint32_t for portability
Change-Id: I8ea57fff72c3b3ed02cc9d82ee295069ca299ed9
2015-07-08 09:27:30 +02:00
Erik van der Kouwe
95b9ecf995 test48: Introduce USENETWORK variable.
This patch introduces USENETWORK environment variable to determine whether to
use the network or not, instead of the unreliable ping test; set to 'yes' to
enable network usage.                                                                      

Change-Id: I9e26fa95b5b990fd94f5978db8de0dd73496d314
2015-07-03 09:50:00 +02:00
Erik van der Kouwe
4d5b0de1fb test48: update lookup name from static.minix3.org to test48.minix3.org
Change-Id: Ie8553bee529aeba66a438eab90177551ec44bc07
2015-07-02 19:01:21 +02:00
Erik van der Kouwe
35a4831d02 clang: apply LLVM patch r201729
This fixes an issue when compiling with GCC 4.9.
For details, see: http://reviews.llvm.org/rL201729

Change-Id: Iaa522715798016f6edb433b01b02aa664fcb5d1c
2015-06-29 10:58:16 +00:00
Ben Gras
b329f2c73b libc: FTS support for dynamic inode numbering
Edited by Lionel Sambuc and David van Moolenbroek.

Change-Id: I29d6383499d8c0524f86f9dcec701aff35ce8a43
2015-06-29 10:58:08 +00:00
f837aff6e8 memory: announce presence during startup
Change-Id: Id4724c444bdca9f72fca05edb55d7614eb5c8286
2015-06-29 10:58:01 +00:00
68afc7715b uds: announce presence during startup
Change-Id: Ibaf2e08e80e2b0c4cf4108fff3866a2bd430ec47
2015-06-29 10:57:54 +00:00
67b4718325 log: announce presence during startup
Set its restart policy to "reset".

Change-Id: I54f350d9d0d9bc571abd9630f27f4c961c7c0778
2015-06-29 10:57:38 +00:00
Cristiano Giuffrida
64d15bd98e libvtreefs: allow highly dynamic directories
Change-Id: Ibf76262f943ef1a5f529384ebd4a06a2cc5897c1
2015-06-29 10:57:31 +00:00
Cristiano Giuffrida
c21aa858e2 libvtreefs: dynamically allocate long inode names
Extended by David van Moolenbroek to continue using static buffers
for short inode names, so as to prevent important file system
services such as procfs from running out of memory at runtime.

Change-Id: I6f841741ee9944fc87dbdb78b5cdaa2abee9da76
2015-06-29 10:57:24 +00:00
Cristiano Giuffrida
5a7def9a94 libvtreefs: fix naming bug
Change-Id: Ib8767cfef4206ed491855bace6dd8bd58b45b8ce
2015-06-29 10:56:59 +00:00
Cristiano Giuffrida
a8f606defa procfs: add service pid information
Change-Id: I163ca4c6c6db45cca41515644ac6c2acd0807ee8
2015-06-29 10:56:53 +00:00
David van Moolenbroek
f5321d8d55 procfs: do not list inactive services
Each /proc/service entry must have a unique label.  With cloning,
multiple RS services may have the same label.  Since we are not
actually interested in inactive services (for now), eliminate those
entries, leaving only the active service which will then indeed have
a unique label in the list.  This resolves a procfs crash.

Change-Id: I0de7ef8fd186ab13f3e22e46416504fd981c09aa
2015-06-29 10:56:43 +00:00
David van Moolenbroek
0eabb93c0c procfs: retrieve both RS tables from RS at once
Previously, procfs would retrieve the rproc and rprocpub tables from
RS in two separate calls.  This allowed for a race condition where the
tables could change in between the calls, resulting in a panic in
procfs under certain circumstances.  RS now implements a new method
for getsysinfo that allows the retrieval of both tables at once.

Change-Id: I5ec22d25898361270c90e805a43fc6d76ad9e29d
2015-06-29 10:56:30 +00:00
David van Moolenbroek
da21d85025 Add PTYFS, Unix98 pseudo terminal support
This patch adds support for Unix98 pseudo terminals, that is,
posix_openpt(3), grantpt(3), unlockpt(3), /dev/ptmx, and /dev/pts/.
The latter is implemented with a new pseudo file system, PTYFS.

In effect, this patch adds secure support for unprivileged pseudo
terminal allocation, allowing programs such as tmux(1) to be used by
non-root users as well.  Test77 has been extended with new tests, and
no longer needs to run as root.

The new functionality is optional.  To revert to the old behavior,
remove the "ptyfs" entry from /etc/fstab.

Technical nodes:

o The reason for not implementing the NetBSD /dev/ptm approach is that
  implementing the corresponding ioctl (TIOCPTMGET) would require
  adding a number of extremely hairy exceptions to VFS, including the
  PTY driver having to create new file descriptors for its own device
  nodes.

o PTYFS is required for Unix98 PTYs in order to avoid that the PTY
  driver has to be aware of old-style PTY naming schemes and even has
  to call chmod(2) on a disk-backed file system.  PTY cannot be its
  own PTYFS since a character driver may currently not also be a file
  system.  However, PTYFS may be subsumed into a DEVFS in the future.

o The Unix98 PTY behavior differs somewhat from NetBSD's, in that
  slave nodes are created on ptyfs only upon the first call to
  grantpt(3).  This approach obviates the need to revoke access as
  part of the grantpt(3) call.

o Shutting down PTY may leave slave nodes on PTYFS, but once PTY is
  restarted, these leftover slave nodes will be removed before they
  create a security risk.  Unmounting PTYFS will make existing PTY
  slaves permanently unavailable, and absence of PTYFS will block
  allocation of new Unix98 PTYs until PTYFS is (re)mounted.

Change-Id: I822b43ba32707c8815fd0f7d5bb7a438f51421c1
2015-06-23 17:43:46 +00:00
David van Moolenbroek
0a2a08739e libfsdriver: clear VM cache only if used
As part of its built-in mmap emulation support for "none" file system
services, libfsdriver clears the VM cache upon exit.  However, for
trivial file systems which do not even support reading from files, the
the VM cache need to be cleared either.  With this patch, the VM cache
is cleared only when modified, so that such trivial file systems need
not be given CLEARCACHE permission.

Change-Id: I518c092443455302b9b9728f10a3f894d2c8036b
2015-06-23 14:38:54 +00:00
David van Moolenbroek
3f30eb69f0 libfsdriver: default to noop for putnode
While putnode requests should always succeed, very simple file system
services may not care about reference counts and thus about putnode
requests at all.  For this reason, we now default to an OK response if
no fdr_putnode implementation is given.

Change-Id: I01f6421abf4546a1f69d8c21900a92d6acc45745
2015-06-23 14:38:28 +00:00
David van Moolenbroek
22840dea11 libfsdriver: preinitialize stat.st_ino
The stat.st_ino field must always be filled with the inode number
given as part of the fdr_stat request anyway, so libfsdriver can
simply fill in the number and allow the file system not to bother.

Change-Id: Ia7a849d0b23dfc83010df0d48fa26e4225427694
2015-06-23 14:38:04 +00:00
Leonardo Fogel
07cbc27cb0 Add a driver for the eMMC on the BeagleBone Black
Change-Id: I30ab36ac048c65538718e372db9502fb8f51d41f
2015-06-21 11:04:16 +00:00
David van Moolenbroek
5055c7ea51 VFS: fix pipe resumption delay bug
Commit 723e513 erroneously removed a yield() call from VFS which was
necessary to get resumed pipe read/write threads to run before VFS
blocks on receive().  The removal caused those threads to run only
once VFS received another message, effectively slowing down activity
on pipes to a crawl in some cases.

Instead of readding the yield() call, this patch restructures the
get_work() code to go back through the main message loop even when no
new work is received, thus ensuring that newly started threads are
always activated without requiring a special case.

This fixes #65.

Change-Id: I59b7fb9e403d87dba1a5deecb04539cc37517742
2015-06-19 22:13:34 +00:00
rlfnb
e1e2bc96d2 handle lack of pckbd more gracefully
kb_init() panics, if no keyboard controller is found during self-test.
Instead of panic, the driver should quit the init process and tell it the SEF .

Change-Id: Icdfb7125f5d4062f46cfbbdbbb9e54ac4b273642
2015-06-15 17:11:29 +02:00
David van Moolenbroek
af4345b097 isofs: do not link against libc
This change requires a small patch to libc, in order to avoid that
libminc has to pull in a large chunk of libc just for mktime(3).

Change-Id: I48e598b3716eff626cac461f78a41e32334e6b28
2015-06-07 17:01:45 +00:00
David van Moolenbroek
44707c1900 inet: do not link against libc
This should make its printed errors show up again.

Change-Id: I6839a584dc2a544bae7973ded3ab1dacf04e4ec0
2015-06-07 14:38:12 +00:00
David van Moolenbroek
dfc3261535 PFS, inet: use static UID to drop privileges
Previously, services would obtain the user ID of "service" through
getpwnam(3).  While this approach is conceptually better, it also
imposes linking against libc which in turn causes problems with
printf(3), which already led to PFS no longer dropping privileges at
all.  For now, we hardcode SERVICE_UID and use that instead.

In the future, two changes should allow removal of SERVICE_UID again:
- "service edit" should cause RS to request that a service (such as
  PFS) drop privileges through SEF, using the user ID resolved by
  service(8), or something similar;
- a future devfs should make it possible for inet to start without
  root privileges altogether.

Change-Id: Ie02a1e888cde325806fc0ae76909943ac42c9b96
2015-06-06 21:42:48 +00:00
David van Moolenbroek
7eb698ea4a VFS: during initial mount, receive but block work
For VFS, initialization is a special case for processing work: PFS
and the ramdisk MFS must be fully mounted before VFS can process any
other requests, in particular from init(8). This case was handled by
receiving reply messages only from the FS service being mounted, but
this effectively disallowed PFS from calling setuid(2) at startup.

This patch lets VFS receive all messages during the mounting process,
but defer processing any new requests. As a result, the FS services
have a bit more freedom in what they can do during startup.

Change-Id: I18275f458952a8d790736a9c9559b27bbef97b7b
2015-06-06 18:45:23 +00:00
David van Moolenbroek
179bddcf5d VFS: fix error behavior for partial pipe writes
This patch fixes two related issues:

- If a large (>PIPE_BUF) pipe write is processed partially, only to be
  followed by a write error condition, then the process is left in an
  incorrect state, possibly causing VFS to crash on a subsequent call.

- If such a partially processed large pipe write ends up resulting in
  an EPIPE error, no corresponding SIGPIPE signal is generated.

The corrected behavior is tested in test68.

Change-Id: I5540e61ab6bcc60a31201485eda04bc49ece2ca8
2015-06-05 18:40:57 +00:00
Jacob Adams
d9494baa34 cawf: Update K&R function declarations
Change-Id: Ib18171089c7b389f7f2643d7298f9659e882f65c
2015-05-18 15:20:39 +02:00
Jacob Adams
c6748a4a93 cawf: Fix buffer scope
Change-Id: I03f9066c20da142034626b07d0b07c446075b8af
2015-05-18 15:20:36 +02:00
Jacob Adams
c14bb31e67 sprofalyze: Fix minor typo
Change-Id: I0a419833fb2f438808613737680ace7246713ee9
2015-05-18 13:54:19 +02:00
Jacob Adams
be4841096d Add manpage for sprofdiff
Change-Id: Ifa98ab133ef818d21921f05db650069448ea52ff
2015-05-18 13:52:13 +02:00
Jacob Adams
2a6b817353 Add manpage for sprofalyze
Change-Id: I206a5878e8f788ea4ff742453148462959263a6a
2015-05-18 13:41:29 +02:00
Jacob Adams
c19d619d42 Importing bin/dd
Change-Id: Ibdfed821aa834419c9713dc80f698c8ed74ff269
2015-04-15 13:50:57 +02:00
Jacob Adams
9cf6cc5098 Import games/caesar and games/rot13
Change-Id: Ib6b074c6c525ee817b9182b17a06ae18851f5afe
2015-04-15 09:47:27 +02:00
Jacob Adams
f1489796fd Add games/banner
Change-Id: Ib4a002422d668d8aa5cf0e7171ea430ef630eeff
2015-04-15 09:47:23 +02:00
Jacob Adams
eb95f895b2 Import games/rain
Change-Id: Ifc9a9d69795e3281f62c3c3438622ce74994b8b0
2015-04-15 08:33:52 +02:00
Jacob Adams
3a1943c1c1 devmand: properly prevent overflow
closes #22

Change-Id: Ia10f352a7ff5b05b1095dbb65d36316f9165a6f0
2015-04-15 08:28:59 +02:00
Jacob Adams
1cd28eb8e4 libc: Fix incomplete fprintf
Closes #23

Change-Id: Ibe6362de0d2d1d94442401b92bc126e63bf9f9b0
2015-03-31 15:45:48 +02:00
Thomas Cort
79444d163d mined: increase the size of the tgetent() buffer.
From the termcap section of the GNU termutils manual:

"There is no way you can tell how much space is needed, so the convention
is to allocate a buffer 2048 characters long and assume that is enough.
(Formerly the convention was to allocate 1024 characters and assume that
was enough. But one day, for one kind of terminal, that was not
enough.)"

Change-Id: Ia5937366ae89e886dbaef7d180bee40669d0c488
2015-03-28 08:39:19 +01:00
Thomas Cort
93cdb3a735 mined: move to minix/usr.bin/mined
As suggested in issue #43.

Historic Locations:

Prior to this commit

  minix/commands/mined

Prior to commit 433d6423c3

  commands

Change-Id: I374ab3ff0e3b9e47779fc21e80b47fda87698242
2015-03-28 08:39:10 +01:00
Thomas Cort
e6df9032b3 mined: remove !__STDC__ code blocks.
__STDC__ is used to mitigate the differences between K&R C and the
ANSI C standard. Nearly every compiler now supports ANSI C, so
there is no need to support non-standard compilers.

Change-Id: Ifc3381ecf1c43dfde9004bee48552d8b3ac4dcdc
2015-03-28 08:38:56 +01:00
Thomas Cort
f3734d6b31 mined.h: use '\a' instead of ascii code for bell.
Makes the code slightly more portable and readable.

Change-Id: I45bbecb6dc1c320c9412eeeaf598116c2ce1aac5
2015-03-28 08:38:48 +01:00
Thomas Cort
e978660932 mined: built without UNIX defined.
* Remove undef NULL, EOF, getchar, putchar
* Rename putchar, getchar, _putchar, _getchar to putch, getch, _putch,
  _getch to avoid conflict with libc functions.
* Rename UP() to UP1() (for UP 1 line) to avoid conflict with UP
  definition in termcap.h. Rename DN1 LF1 RT1 for consistency.
* Add termcap.h for prototypes for tputs and friends.
* Add libterminfo references to Makefile
* Add return value to _putch() to make it work as tputs expects.
* Make putch() call _putch()
* Remove UNIX ifdefs and all code in the !UNIX branches.

closes #43

Change-Id: I0a6f7298aa8b12a74225badc88d3c236a02669ea
2015-03-28 08:38:33 +01:00
Thomas Cort
fc850d580c man: clean-out man1x category.
Removes the following man pages:

* awk.1x -- for a version of awk we no longer have
* kermit.1x -- seems gone altogether
* macros.1x -- not useful for anyone anymore

Moves the following man pages:

* mined.1x -- Moved to minix/commands/mined/mined.1
and reformatted to use the mdoc macros instead of the
Minix macros so that it displays properly.

Removes /usr/man/man1x from the directory tree.

closes #44

Change-Id: I59b8bd54cf5cba6d188e51e99a92b36e90c275c1
2015-03-25 06:53:44 +01:00
Thomas Cort
d1a87c1f64 mined: clean-up trailing whitespace.
Change-Id: Ic27293d7e1d0f830d635b78e7e620dcf0ef3e03f
2015-03-24 14:03:03 +01:00
Thomas Cort
d131b58784 mined1.c: remove i386 guard around escape sequences.
The escape sequences for the function keys used to be separated
out in older versions of Minix when they were different for m68k
and intel. Support for m68k was dropped and that code was
removed, leaving the ifdef i386. Since the sequences are the
same for i386 and arm, there is no need to keep the ifdef i386.

Change-Id: Id96a80bcb24da120efa63acc9b248d87fc347eac
2015-03-24 14:03:03 +01:00
Thomas Cort
6a0aa6fb5e mined.h: remove irrlevant comment.
It used to refer to several NIL_* definitions. Those were removed
in commit 6e25ad8b0a leaving the
comment with nothing to comment on.

Change-Id: I52221ae5d2c5216e82391b480cf2038ad723b8f0
2015-03-24 14:03:02 +01:00
Thomas Cort
0cf05b213d mined.h: remove unused definition, MEMORY_SIZE.
Change-Id: I1ae83c427cafb15f1382b7d8ab3871a36b0eec28
2015-03-24 14:03:02 +01:00
Thomas Cort
50d246bbba mined.h: remove minix/config.h include.
Nothing defined there is used by mined.

Change-Id: I38b692be1313aaed316eebd7caf8e879178d90dc
2015-03-24 14:02:41 +01:00
Jacob Adams
d82c151c9e commands/fix: create manpage for fix(8)
Change-Id: I868f1338994d6cc2cba6789b9b4e8934610d0142
2015-03-24 08:21:14 +01:00
rlfnb
31ba042920 Fix boot if no pckd device is there
Trying to boot Minix3 master on an appliance/sbc like ALIX fails, as
the service command throws an error. Making the rc script more robust
solves it.

Change-Id: I659043cbbaa2d67b70d6d6e5ab14fff8e1bba769
2015-03-23 14:57:06 +01:00
Jacob Adams
80c94e3974 swifi: Fix incorrect memset
Change-Id: I6764aff558f51cdb90b91a3e71c982e8b3f47058
2015-03-23 14:56:59 +01:00
Jacob Adams
056ece2898 Update whatis/apropos database configuration
Change-Id: I2483cc0e9748ba68bd1acf0ceb39fde4afc2059b
2015-03-23 11:11:49 +01:00
Jacob Adams
f113a7238f Make rotate manpage more detailed
Change-Id: I028550c17b87655a6e39a7f8b3233cbe982883eb
2015-03-23 11:06:37 +01:00
426224bbc6 release.sh: Support preinstalled package selection
This allows to both override the default package repository and
preinstalled packages list from the command line or the environment.

Also use everywhere PACKAGEURL.

Change-Id: I3434ff53be769f8d0f890bb5fb44521a0017e123
2015-03-20 11:17:24 +01:00
Christian Koch
6f55e9f11d nonamed.8: Document the -L option.
Change-Id: I1aadb50cd416e0467a87c8d75db1c293333a7969
2015-03-19 10:00:56 +01:00
Jacob Adams
271999a2f3 Do not read past the end of the buffer
closes #22

Change-Id: I239c670915d98440c176ccf23e5270c40c4fbe81
2015-03-18 08:29:46 +01:00
Jacob Adams
e3cf9c04f1 properly check if configuration file is opened
closes #21

Change-Id: I2f83b5385ac38bf07d30acb14f40c14bec476830
2015-03-18 08:25:19 +01:00
Jacob Adams
3bdcd28869 Get rid of K&R functions in recwave
Change-Id: I98cf0426aedf03ec0312f58ff77b816fd231eb84
2015-03-18 08:21:31 +01:00
Jacob Adams
25223c2ae2 Check argc is greater than 1 before using on argv
closes #19

Change-Id: I50ee3fa82bce274e710434628b6c178467fd3887
2015-03-18 08:20:08 +01:00
Emmanuel Blot
41b870c890 arm: Make sure __k_unpaged_MINIX is first
Do not rely on build order to set startup symbol (`__k_unpaged_MINIX`)
at kernel binary start

Change-Id: I1ed3f9309fe66ff97e24915938c114d5a159deaf
2015-03-18 07:50:31 +01:00
Emmanuel Blot
54841c0102 Fix incorrect sanity check
Remove invalid sanity check where an array is tested against NULL -
not a pointer

Change-Id: I3d5e33585e7f97a41124af4133e8a879ab21d972
2015-03-18 07:49:44 +01:00
Emmanuel Blot
4f89addcc1 Fix unused variable warnings
Do not define variables that are not used in Minix builds

Change-Id: I11d12e5e1de9fc359b71a7e7534fc8f09fac837d
2015-03-18 07:49:03 +01:00
Emmanuel Blot
d91890d288 Fix format string for size_t types
Fix missing “%z[dux]” prefix printf formatter string for `size_t`
types.

Change-Id: If216a778b0b65e8ab2cdd1c7484cb8452d1f965d
2015-03-18 07:48:09 +01:00
Jacob Adams
61890c3b2e Change rotate.sh BZIP2 to the correct path
closes #8

Change-Id: I90cb30e3d8ee2c000aca36fb9f8cc22c6d49583e
2015-03-14 16:43:04 +01:00
Robin Karlsson
e3b78ef14f Import NetBSD games/rogue
Change-Id: Id4aef4950f250edef2d507910877aabc6b9580ea
2015-03-14 14:59:16 +01:00
Jacob Adams
1b6a97c9c0 commands/autopart: Fix dead code block
Fix dead code block, make surrounding code more readable, and remove
unused mode variable.

closes #20

Change-Id: I802e3d8680d7a7adc7acd580bfcec9dc28af0bc4
2015-03-13 18:53:05 +01:00
Jacob Adams
dc0077241b Use or instead of and to determine if urb is valid
close #24

Change-Id: I12e2b20d69aa7b186a8e5cd0dc16f653a18b2ee2
2015-03-11 17:56:09 +01:00
rlfnb
7171c2321f Maybe a broken bios/device setting
Removing the panic leads to exactly one message on ALIX. Both commits
make minix out of the box booting on ALIX devices.

Change-Id: I9210fef79a8736e36b9c42c7925c9f3354c60e7c
2015-03-11 13:46:45 +01:00
rlfnb
b56a9d4725 ALIX: No pci device at bus 0, dev 0, func 0
Seems like its a kind of convention introduced by Intel but not
mandatory from a PCI specification point of view, that the PCI host
controller resides on bus 0, device 0 function 0. At least tinybios
(the bios used by ALIX and WRAP) based appliances are not able to boot
with this change.

Change-Id: I0e45c68c482972be7276028525985de920cf64f7
2015-03-11 13:46:41 +01:00
3d0f2c86c4 Fix arm build for GCC, noassert, -Os
Change-Id: I706fdfc8fc9a5e0c9076e3657ac1a6ef0745bd14
2015-03-05 15:42:21 +01:00
David van Moolenbroek
f912036bae libsffs, libvtreefs: fix getdents bug
Bad logic introduced as part of the fsdriver changes could cause
getdents to terminate early in these libraries.

Issue reported by r0ller.

Change-Id: If450d5ea85e830584878d8a4ec0f00519355a353
2015-02-10 13:47:29 +00:00
David van Moolenbroek
75e18fe498 Add 3c90x: 3Com 3C90xB/C network driver
Change-Id: Iba0bbcb3b1b69a7c204abdc81cf3afe59b6bfaae
2015-02-10 13:47:28 +00:00
David van Moolenbroek
3814aed560 libsa: add string precision support to vprintf
We already had a hack to ignore the precision, but the ACPI driver
requires an actual implementation--it prints garbage at the end of
some strings otherwise.  This patch adds support for precision for
strings only, limiting printing to the given number of characters.
For all other specifiers, precision is still unsupported.

Change-Id: I1d41fc70a0d0494db695c22ba609262a50b86e08
2015-02-10 13:47:28 +00:00
David van Moolenbroek
2a3bc70264 ACPI: OS-dependent code tweaks
Change-Id: I533685f6716cb48ccf3d5ca5ef0fb681a5293549
2015-02-10 13:47:28 +00:00
David van Moolenbroek
3b0299dd65 bootloader: pass memory map to kernel
Previously, the bootloader would only provide a single memory range.
At least on VirtualBox, this memory range includes the ACPI tables,
which the kernel then happily overwrites when executing VM.  Much of
the infrastructure to use a fullblown memory map is already in place;
this patch adds the last (and strangely missing) bit of generating
the memory map in a multiboot-compatible way.

It should be noted that both the bootloader and the kernel actually
violate the multiboot specification by not packing the structure for
the memory ranges.  This is a NetBSD bug, but it is also a nonissue
for (our) practical purposes.  It can be fixed without changing the
code added in this patch.

Change-Id: I7c0a307a8a8133239531e1d2b80f376849f90247
2015-02-10 13:47:28 +00:00
David van Moolenbroek
29492bb71c ACPI: upgrade to acpica-unix2-20141107
Change-Id: I96151a2756fd9814bfba180548e8a96dca63ce51
2015-02-10 13:47:27 +00:00
David van Moolenbroek
f202792edf VM: fix for handling one-shot page memory
The original one-shot page patch (git-e321f65) did not account for the
possibility of pagefaults happening while copying memory in the
kernel.  This allowed a simple cp(1) from vbfs to hang the system,
since VM was repeatedly requesting the same page from the file system.

With this fix, VM no longer tries to fetch the same memory-mapped page
from VFS more than once per memory handling request from the kernel.
In addition to fixing the original issue, this change should make
handling memory somewhat more robust and ever-so-slightly faster.

Test74 has been extended with a simple test for this case.

Change-Id: I6e565f3750141e51b52ec98c938f8e1aa40070d0
2015-02-10 13:47:27 +00:00
6c30d22a56 Allow u-boot repository URL to be overridden
This allows the URL used to clone our specific version of u-boot to be
specified in the environment, instead of being hard-coded.

This new flexibility will be required by the new Continuous Integration
infrastructure, whose test nodes are in a network without direct
internet access.

Change-Id: I7440b5bba6786f979623b4509111e4e99c6558f6
2015-02-05 14:04:31 +01:00
Thomas Goering
e1131d9c96 recognize Intel 82540EP LP by e1000
Change-Id: I8868963ba09ce1dffa9416c9ece29c7315dee4cd
2014-12-12 21:28:06 +01:00
Ben Gras
5ae1a533c7 ARM: can build with llvm, switch to EABI
. bitcode fixes
	. switch to compiler-rt instead of netbsd libc functions
	  or libgcc for support functions for both x86 and arm
	. minor build fixes
	. allow  build with llvm without crossbuilding llvm itself
	. can now build minix/arm using llvm and eabi - without C++
	  support for now (hence crossbuilding llvm itself is turned off
	  for minix/arm)

Change-Id: If5c44ef766f5b4fc4394d4586ecc289927a0d6eb
2014-12-12 13:04:56 +01:00
41ba8c04cc Restart policies: Add testing and ProcFS DB
- Expose in procfs the service status and supported recovery policies.
 - This adds a test (testrelpol.sh) to exercise the restart policies of
   the system services and drivers.

NOTE:
  The policy support information is temporarily hardcoded in ProcFS, but
  this has to be replaced by properly retrieving this information from
  RS, which should in turn be setup on a per service basis, at
  initialization time.

Change-Id: I0cb1516a450355b38d0c46b1a8b3d9e841a2c029
2014-12-10 23:11:25 +01:00
Ben Gras
ad8bffad67 ARM: remove minix type exception
. clean fix for minix/arm llvm build problem
	. was needed for gcc but isn't any more it seems

Change-Id: Iea1edffbe3149c5c954ae009a388b7ea492f3d1a
2014-12-10 16:46:29 +01:00
David van Moolenbroek
5260f07c2c virtio_net: use new libnetdriver
Change-Id: Id06bdb67da12477984b42bbd46623bd8f25c0ab9
2014-12-04 12:10:52 +00:00
David van Moolenbroek
d76bd1f07c rtl8169: use new libnetdriver
Change-Id: Ia26b6c440a1525f1d2bb9e7592e357dac0ba602c
2014-12-04 12:10:52 +00:00
David van Moolenbroek
4081bff625 rtl8139: use new libnetdriver
Change-Id: Iba941653b7c052375694bcec2561957c1979feb0
2014-12-04 12:10:51 +00:00
David van Moolenbroek
bcc1b08c61 orinoco: use new libnetdriver
Change-Id: I003590539dd76f4be8e067f986bb1f17b151490d
2014-12-04 12:10:51 +00:00
David van Moolenbroek
6315775f16 lance: use new libnetdriver
Change-Id: If3414088e66407c688c4960f99a165b0ee1ebc83
2014-12-04 12:10:51 +00:00
David van Moolenbroek
5af3c2565f lan8710a: use new libnetdriver
Change-Id: Iaee4d75a5dfafc72d94f0b02681f9aea1c9da535
2014-12-04 12:10:50 +00:00
David van Moolenbroek
96e62d65b6 fxp: use new libnetdriver
Change-Id: I03268655a5daff3d109ae52e64673911ef096a3f
2014-12-04 12:10:49 +00:00
David van Moolenbroek
1ad10e3ae0 e1000: use new libnetdriver
Change-Id: I111750d2ca27f01039d0b427b1314aea861e2074
2014-12-04 12:10:49 +00:00
David van Moolenbroek
91c4db251e dpeth: use new libnetdriver
Change-Id: Ic389e54817c5b241dad851c89ef1cf16c015a79b
2014-12-04 12:10:49 +00:00
David van Moolenbroek
3913e49004 dp8390: use new libnetdriver
Change-Id: Ieaf6d605832d475f95fd9b06026b349dce7ee025
2014-12-04 12:10:49 +00:00
David van Moolenbroek
29018b4ecd dec21140A: use new libnetdriver
Change-Id: I54be3b770e4d1fd320200c30e9e9073a7c1b405b
2014-12-04 12:10:48 +00:00
David van Moolenbroek
b80fc5be89 atl2: use new libnetdriver
Change-Id: I65de5d29a75d5f3101b2c5ab16a4b0d79bd77cc3
2014-12-04 12:10:48 +00:00
David van Moolenbroek
dbcce9ddb0 libnetdriver: turn into network driver framework
The new implementation of this library provides abstractions for
network drivers, and should be used for all network drivers from now
on.  It provides the following functionality:

  - a function call table abstraction, hiding the details of the
    datalink protocol with simple parameters;
  - a state machine for sending and receiving packets, freeing the
    actual driver from keeping track of pending requests;
  - an abstraction for copying data from and to the network driver,
    freeing the actual driver from dealing with I/O vectors while at
    the same time providing a copy implementation which is more
    efficient than most current driver implementations;
  - a generalized implementation of zero-copy port-based I/O;
  - a clearer set of policies and defaults.

While the concept is very similar to lib{block,char,fs,input}driver,
one main difference is that libnetdriver now also takes care of SEF
initialization, mainly so that aspects such as recovery policies and
live-update aspects can be changed for all network drivers in a
single place.  As always, for the case that the provided message loop
is too restrictive, a set of more low-level message processing
functions is provided.

The netdriver API has been designed so as to allow alleviation of one
current protocol bottleneck: the fact that at most one send request
and one receive request may be pending at any time.  Changing this
aspect will however require a significant rewrite of libnetdriver,
and possibly debugging of drivers that are not able to cope with (in
particular) queuing multiple packets for transmission at once.

Beyond that, the design of the new API is based on the current
protocol, and may be changed/extended later to allow for non-ethernet
network drivers, exposure of link status, multicast address
configuration, suspend and resume, and any other features that are in
fact long overdue.

Change-Id: I47ec47e05852c42f92af04549d41524f928efec2
2014-12-04 12:10:48 +00:00
David van Moolenbroek
107df7c8fa e1000: convert to KNF
Change-Id: Ibd156c2e0a58fed70895080d4b230b26c500fa11
2014-12-04 12:10:48 +00:00
David van Moolenbroek
1539606d98 atl2: convert to KNF
Change-Id: Ie4b979aab3127a91a12b8086326da0eb1f9a860b
2014-12-04 12:10:47 +00:00
David van Moolenbroek
d1db724f47 libvirtio: expose result size on packet dequeue
Change-Id: I49304678895779849abc2528a9f78730f968e712
2014-12-04 12:10:47 +00:00
David van Moolenbroek
a810336026 orinoco: restore register memory mapping
Untested.

Change-Id: I439f0e711e16ba478dadf57ffc8ad74ec19ea1b9
2014-12-04 12:10:47 +00:00
David van Moolenbroek
2e5374621d fxp: enable bus mastering if needed
This is required for at least QEMU.  However, as of writing, QEMU also
requires fixes in its epro100 emulator before this driver can use it.

Change-Id: Ie5c5ffe4311b1a0e581bc687f1c15de3a85f4a30
2014-12-04 12:10:47 +00:00
David van Moolenbroek
92293fafd3 e1000: fix unaligned register access
This resolves a guru meditation in recent VirtualBox versions.

Change-Id: I5034d8af1fe885adda3c027cb23563bffaccf97e
2014-12-04 12:10:46 +00:00
David van Moolenbroek
4bf270019a dp8390: update, allow default port and IRQ
Bochs has switched from port base 0x240 to 0x300 for its default
NE2000 ISA configuration, and QEMU is using the same settings.

Change-Id: Ide6cdb14321eb4324d0bf6d6314c5970b3493e95
2014-12-04 12:10:46 +00:00
David van Moolenbroek
cb796b7551 etc/usr/rc: fix argument passing for net drivers
The expected argument name would include the instance number, which
is not only redundant in many cases (FOOETHn_n=arg.., "n" being the
instance number) and conflicted with what netconf(8) does, but some
drivers need to be able to see the arguments for all instances of its
driver type--for example, dp8390 needs to know how many earlier
instances have been configured to use PCI.

Change-Id: I4830b823352722f554a032979464aba8b08fc166
2014-12-04 12:10:46 +00:00
David van Moolenbroek
cc5b198875 UDS: move from drivers/net/ to net/
Change-Id: I53992b205e767a77c7b3c868a38c7f3d772a4ed3
2014-12-04 12:10:46 +00:00
Ben Gras
3c8950cce9 minix/ changes for arm llvm build
. fixes needed to build Minix/ARM with LLVM without errors,
	  mostly size_t cleanness

Change-Id: If4dd0a23bc5cb399296073920a8940c34b4caef4
2014-12-03 23:40:56 +01:00
Ben Gras
7f59afadd5 Fix for TOOL_CPP
. needed for xorg build from /usr/xsrc

Change-Id: I632c9d09d4cfecfbf454820551f6d618ac4f4ebe
2014-11-28 07:22:52 -05:00
0805ab8cfd Import a few manpages
The following manpages where contributed by
Jacob Adams <tookmund@gmail.com>:
 - atnormalize.8
 - autopart.8
 - decomp16.1
 - devsize.8
 - rawspeed.8
 - rotate.8
 - update_bootcfg.8
 - updateboot.8

Change-Id: Ide3abf0962083b83e37426e2d47f3a9391d6315e
2014-11-25 11:04:20 +01:00
Ben Gras
99e9e03701 for pkgsrc without base clang from sambuc@
Change-Id: Id0bf33da426f6c7a14628846dd1185cdcdfac766
2014-11-25 10:52:02 +01:00
Ben Gras
3a9e392b3a remove unused PSW restore code
. now done in-kernel so IOPL gets restored

Change-Id: I9905d2844a4715004054a788613ff7efd02a227d
2014-11-25 10:51:01 +01:00
Ben Gras
c9278f9170 restore PSW like 9393439a20 for AMD syscall
Change-Id: Ide0a8727af8d0d81361382dbd2460c7a6c5743fc
2014-11-24 12:05:45 +01:00
David van Moolenbroek
65eccd1f74 inet: detect short TCP option lengths
Previously, a TCP option length of zero would cause inet to end up
in an infinite loop.

This resolves #7, reported by Alejandro Hernandez.

Change-Id: I45ad4c789d10d8e202cf6e140a7b9db7a6543c75
2014-11-18 12:53:18 +00:00
db1ca87b7d Fix for missing /usr/games in root's PATH
After importing the default environment from NetBSD, we discovered that
it doesn't contain /usr/games, which is required for the commands
strfile. This utility is used while generating fortune database.

This patch simply sets TOOL_STRFILE to contain an absolute path.

Change-Id: I2e366a0b67d5258f387c3f5a2a2a581fedead359
2014-11-17 22:35:00 +01:00
David van Moolenbroek
aa4ee93d43 dhcpd: don't crash so easily
The jump-to-start hack is not resetting global variables, resulting in
a crash after several such restarts cause an overflow in the network
table.  This patch fixes that particular issue, but more similar
issues (in particular memory leaks) are bound to come up.  As such this
is a stopgap measure until we can get rid of the old dhcpd altogether.

This resolves the additional issue reported in #2.

Change-Id: Ic4cd80eae520cf2b97e893bac63b3ab1ecfea6d8
2014-11-17 20:17:43 +00:00
David van Moolenbroek
b49f4cacde rtl8139: enable bus mastering if needed
This resolves #2.

Change-Id: Ie6736f0d5a713025f09c18de7042ba44fbb1b2f8
2014-11-17 19:23:00 +00:00
David van Moolenbroek
e321f65582 libfsdriver: support mmap on FSes with no device
This patch adds (very limited) support for memory-mapping pages on
file systems that are mounted on the special "none" device and that
do not implement PEEK support by themselves.  This includes hgfs,
vbfs, and procfs.

The solution is implemented in libvtreefs, and consists of allocating
pages, filling them with content by calling the file system's READ
functionality, passing the pages to VM, and freeing them again.  A new
VM flag is used to indicate that these pages should be mapped in only
once, and thus not cached beyond their single use.  This prevents
stale data from getting mapped in without the involvement of the file
system, which would be problematic on file systems where file contents
may become outdated at any time.  No VM caching means no sharing and
poor performance, but mmap no longer fails on these file systems.

Compared to a libc-based approach, this patch retains the on-demand
nature of mmap.  Especially tail(1) is known to map in a large file
area only to use a small portion of it.

All file systems now need to be given permission for the SETCACHEPAGE
and CLEARCACHE calls to VM.

A very basic regression test is added to test74.

Change-Id: I17afc4cb97315b515cad1542521b98f293b6b559
2014-11-15 11:19:52 +00:00
David van Moolenbroek
289b04677a libfsdriver: prefill st_dev for stat requests
This obviates the need for several file system implementations to
remember the device on which they are mounted.

Change-Id: Ida8325cf4bcf072e61761cfee34e3f7ed2d750b9
2014-11-14 15:54:16 +00:00
David van Moolenbroek
31b6611abf procfs: add /proc/service directory
This directory is filled dynamically with regular files, one for each
service that RS knows about, named after its label.  Its contents are
still subject to (heavy) change, but currently expose the service's
endpoint and number of restarts so far.

Change-Id: Ie58c824bcb6382c8da7a714e59fee87329970b4b
2014-11-12 12:13:53 +00:00
David van Moolenbroek
f1abbce725 procfs: convert to KNF
Change-Id: Ib4252f199af0f9597745dcd2c11a7f761738671f
2014-11-12 12:13:47 +00:00
David van Moolenbroek
52be5c0afb libvtreefs: API changes/extensions, part 2
- rename start_vtreefs to run_vtreefs, since the function returns upon
  termination these days;
- add get_inode_slots function to retrieve the number of indexed slots;
- add support for extra per-inode data for arbitrary storage.

Change-Id: If2d365d7b478a1cecc9e20fb2b3e70c1a1cf7243
2014-11-12 12:13:43 +00:00
David van Moolenbroek
5eefd0fec2 libvtreefs: API changes/extensions, part 1
- move primary I/O buffer into vtreefs; change read hook API;
- add hooks for write, truncate, symlink, mknod, unlink, chmod/chown;
- modernize message_hook;
- change procfs, devman, gpio accordingly;

Change-Id: I9f0669e41195efa3253032e95d93f0a78e9d68d6
2014-11-12 12:13:38 +00:00
David van Moolenbroek
693ad767e8 libvtreefs: convert to KNF
Change-Id: I81bdf05c9b630a0cbb0ac573d36d4f59f8137199
2014-11-12 12:13:33 +00:00
Emmanuel Blot
f92baba71c Fix bad cast from u16_t to ssize_t 2014-11-12 12:13:28 +00:00
David van Moolenbroek
7ee000e54a procfs: compile in x86 support only for x86 target
Issue reported by Emmanuel Blot.

Change-Id: I7f5b1b65273e6ac841d5451e0be7b0e1c92d537c
2014-11-12 12:13:23 +00:00
David van Moolenbroek
a8a812ef6a test76: increase alarm times
The test would sometimes fail because an alarm triggered before the
system call to be interrupted by the alarm could be started.

Change-Id: Ia507720a1f2d259afde1f97b7edd03f22cbd4810
2014-11-12 12:12:40 +00:00
David van Moolenbroek
8b18d03deb trace(1): document how to add an IOCTL handler
Also fix two small IOCTL-related bugs:
- do not print an argument pointer for argument-less IOCTLs;
- print IOCTL contents with -V given once, just like structures.

Change-Id: Iec7373003d71937fd34ee4b9db6c6cec0c916411
2014-11-12 12:02:29 +00:00
David van Moolenbroek
92601f58cb ext2: perform super I/O with contiguous memory
Issue reported by Antoine Leca.

Change-Id: Ie6f3ab6c1943b0b7ea9d5a68d4c24b92bab17233
2014-11-11 21:43:55 +00:00
Ben Gras
f53651de01 VM,MFS: better handling of some exceptional cases
Fix for problems reported by Alejandro Hernández:
	. VM unmap: handle case where there is no nextvr

Fixes for problems found by running Melkor ELF fuzzing tool:
	. VM: better handle case where region prealloc fails by
	  freeing memory that was allocated so far
	. MFS fs_readwrite: EOF check should happen for read and
	  peek requests, not just read

This fixes #4.

Change-Id: I2adf4eebdfb4c48a297beff0478eed5c917a53a4
2014-11-10 17:51:57 +01:00
957802cd0c Import NetBSD shell environment files
With the import of Xorg, a proper separation between login-time and sub
shell-time of the environment setup is necessary.

Instead of re-developping this from scratch, I am taking the opportunity
to import the NetBSD default environment.

Change-Id: Ib6a8fbd9c2f407ccd59be57a52ef9df21c2c9ce7
2014-11-10 16:48:56 +01:00
123aceb045 Adding /usr/X11R7/lib to LD_LIBRARY_PATH
Change-Id: I94b91e9e89115f90142e284fca21df4c3c8e2060
2014-11-10 14:43:29 +01:00
86b0b2ca84 Adding /usr/X11R7 to PATH
Change-Id: Ifac54e59715f48bdfa4ab0a77d656d11f7289a2e
2014-11-10 14:43:29 +01:00
971bb1a587 Importing external/mit/xorg support rules
Change-Id: Ib11d8659485a444797bf3a2118182a1d4e316b50
2014-11-10 14:43:29 +01:00
1230fdc108 external/mit/expat: Import
Change-Id: Ieb49357166b392956df6554a06fcae83c8fd519d
2014-11-10 14:43:28 +01:00
9e77ef5013 Enhancing /proc/pci
- Adding missing fields for PCI device lookup
 - Adding the domain (for now set to zero) as part of the slot name

Change-Id: Iebaf3b21f6ab5024738cbc1dea66d5ad3ada175d
2014-11-10 14:43:27 +01:00
5d8311761a Turn PCI into a character driver
Change-Id: Ia9c83af4d52e82e845b6a847c3e82e33d1920ae0
2014-11-10 14:43:27 +01:00
3641562f44 Use NetBSD PCI ID DB
Change-Id: I3fcbce5983b4e0b45e6cc8fac076947c6a84928d
2014-11-07 16:20:39 +01:00
7eb99bda90 Importing lib/libpci
Change-Id: I21ae1e409286cec27c5e35677de3778a3f505d1e
2014-11-07 16:20:39 +01:00
6e7bb62853 PCI driver cleanup
- Moved to KNF
 - Whitespace cleanup
 - Removed useless static functions prototypes
 - Renamed some file private functions by prepending '__'
 - Renamed some server-specific function by prepending '_'
 - Fixed compilation warning for WARNS= 3

Change-Id: Ie44d35839177d5ee0630cdf576660c852452ab80
2014-11-07 16:20:39 +01:00
3d3105466a PCKDB: Fix PS/2 Mouse support.
Change-Id: I2240b47ca47a3db7268b47e9e5881d8200c68531
2014-11-07 16:20:39 +01:00
9393439a20 Fix iopl flag when sysenter/exit are used
Change-Id: If8c12f987c3adb8f329ae163da6b2f1cb8cc772f
2014-11-07 16:20:39 +01:00
David van Moolenbroek
521fa314e2 Add trace(1): the MINIX3 system call tracer
Change-Id: Ib970c8647409196902ed53d6e9631a1673a4ab2e
2014-11-04 21:46:31 +00:00
Thomas Veerman
10b559663e buildsystem: fix build errors for x86 on OSX
Define _NLS_PRIVATE in tools/llvm-tblgen/Makefile so that
<tools/compat/nl_types.h> will pull in <include/nl_types.h>. This is
necessary as Clang's c++/v1/locale implementation contains references
to catopen and other catalog symbols that aren't defined anywhere.
Moreover, the compiler will complain about NL_CAT_LOCALE not being
declared. The compat nl_types.h fixes these discrepancies.

However, <nl_types.h> uses __format_arg to add function attributes to
declarations. On NetBSD __format_arg(fmtarg) is defined by
<sys/cdefs.h> to be __attribute__((__format_arg__ (fmtarg))) for
briefness, but other platforms don't do that. Consequently, the build
will fail on catopen and friends function declarations because the
compiler doesn't know how to handle __format_arg(fmtarg). A fixup to
<tools/compat/nl_types.h> takes care of this, but it won't win any
beauty contest.

Change-Id: Ic4426eca8385aeef858e60304d6e8c06cd497d95
Signed-off-by: Thomas Veerman <tveerman@gmail.com>
2014-11-04 11:00:29 +01:00
David van Moolenbroek
cb3a6387c8 VM: fix returning VFS error code for mmap
Change-Id: Ifcaa15fb8277be53515eb18c4f86a306c52d91d6
2014-11-03 11:19:08 +00:00
David van Moolenbroek
1f945e8080 Fix fcntl(F_[GS]ETNOSIGPIPE) semantics
The new semantics should match those of NetBSD and other systems.

Change-Id: Ic9ca9d6b8c3e42d2a2953d9feea5f6bacaceb43c
2014-11-01 12:57:31 +00:00
David van Moolenbroek
10b1b4ee12 devman: allow multiple event read calls up to EOF
Read calls may be repeated by VFS if the user destination memory is
not mapped in.  Devman currently assumes that all reads are
successful, and uses this to track whether EOF has been reached for
a particular event, discarding it as soon as this happens.  Upon
repetition, this may result in lost events for devmand.

With this patch, devman discards events only once devmand reads the
EOF marker, which itself can never generate a user page fault.  The
result is that read calls for data can be repeated safely, without
the risk of losing events in the process.

Change-Id: I9dfdf7f8c8992a20a10302d79c3506e61f8564b0
2014-10-28 14:43:33 +00:00
Thomas Veerman
e1c7263ee4 Fix build error on OSX
When building Gold on OSX 10.9 and Clang 6.0, the build process fails
with the error:

In file included from /Users/thomas/minix/tools/binutils/../../external/gpl3/binutils/dist/gold/binary.cc:31:
In file included from /Users/thomas/minix/tools/binutils/../../external/gpl3/binutils/dist/gold/stringpool.h:23:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/string:438:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cwchar:107:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cwctype:54:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cctype:51:72: error: use of undeclared identifier 'do_not_use_isalnum_with_safe_ctype'
inline _LIBCPP_INLINE_VISIBILITY int __libcpp_isalnum(int __c) {return isalnum(__c);}

Signed-off-by: Thomas Veerman <tveerman@gmail.com>
Change-Id: Ib7ca13a51e83c31bb3020d755e04b308aeacde5d
2014-10-10 12:56:50 +02:00
ce3cb94487 Fix OS X crossbuilds for arm
- Fixed missing variable interpolation because of single quotes
 - Replaced /bin/sh in gen_uEnv.txt.sh with /usr/bin/env bash as the default
   echo doesn't support '-n'
 - Fixed some whitespace errors
 - A succesful build requires for now to skip the gold linker on OSX.

Change-Id: Id09bf52f45252026e3a58b74e8448ea24a0dab12
2014-10-10 12:56:41 +02:00
David van Moolenbroek
eda6f5931d Import tmux
We have to use SOCK_SEQPACKET instead of SOCK_STREAM for client/server
communication, because UDS does things with control messages that tmux
does not expect.

Change-Id: I3edb1875d61fb976cf6485c650f4fd4b82fa354c
2014-10-03 10:01:08 +00:00
David van Moolenbroek
5d259c7f93 libc: enable setproctitle(3)
Change-Id: I31bbc5d960c60f7347424ce3d8f4bce89b396339
2014-10-03 10:01:03 +00:00
David van Moolenbroek
e985b92992 Import libevent
Change-Id: Ic75f4cac5eb07ffaba8f97d10673d7d7e2b1762d
2014-10-03 10:00:53 +00:00
David van Moolenbroek
65f76edb8f minix libraries: resolve clang warnings
Change-Id: I0f3425fb8838708c9848a006f1eee5ab1bad71d2
2014-09-30 21:04:09 +00:00
David van Moolenbroek
5dd8da10c5 libc: resolve minix clang warnings
Change-Id: If6c42f7346cc1b00b387ae8d3b4f0df3ffb0244f
2014-09-30 20:35:56 +00:00
David van Moolenbroek
685aa79304 libsys: resolve clang warnings
Change-Id: Ic954ba8667b4d039172b8e0d2ec57674a479b8aa
2014-09-30 20:08:54 +00:00
David van Moolenbroek
d794ecc9ef Replace NetBSD grep with OpenBSD grep
The NetBSD version is seriously broken--it is unable to match lines
against an empty pattern--and appears to be unmaintained.

The new version is the latest OpenBSD grep, with a number of MINIX-
specific changes marked as such, and an additional number of
(signed/unsigned, const) fixes to pass compilation.

Since this is not NetBSD code, move back the entire thing into
minix/usr.bin.

Change-Id: Icd40794a2d0cff9e7fb452db7d28c16dbd25e51d
2014-09-30 18:09:56 +00:00
David van Moolenbroek
94e65446c4 libsffs: make path names constant
And a few other related warning fixes.

Change-Id: I1a49b9ee04c2b1bf80bc943272f72ffd6de77ef6
2014-09-30 12:48:10 +00:00
David van Moolenbroek
1dcfbcd173 Remove support for call profiling
The entire infrastructure relied on an ACK feature, and as such, it
has been broken for years now, with no easy way to repair it.

Change-Id: I783c2a21276967af115a642199f31fef0f14a572
2014-09-30 12:39:03 +00:00
David van Moolenbroek
e5808135dd test56: fix race condition
Change-Id: I42bfe2b150e92f760794b4a03e62859c8bd7a992
2014-09-29 16:16:36 +00:00
David van Moolenbroek
cbc8a0df90 tests: fix clang warnings
Change-Id: I5dddc85169d7ef515c99dd1ab824573cbc1b5f2b
2014-09-29 16:16:32 +00:00
David van Moolenbroek
e296281ce2 VFS: do not make cloned devices setuid/setgid
Change-Id: Ifd97444dd54334ccbc8780df9473450998ab7489
2014-09-29 16:16:27 +00:00
David van Moolenbroek
6990e61341 Remove obsolete MIOC(UN)MAP requests
Change-Id: I915ac759bc80a50aad21c12f088ad6c345a42986
2014-09-29 16:16:22 +00:00
David van Moolenbroek
f4bd5678c6 sys/ioccom.h: remove _MINIX_IOCTL_IORW
It is unused, and does not do what the context suggests it does.

Change-Id: Ic5df9c77e2566a7754e01a444126a6caad2850fc
2014-09-29 16:16:17 +00:00
David van Moolenbroek
f737eea636 svrctl(2) update
- synchronize request type with ioctl by making it unsigned long;
- unbreak VFS requests, as they were being sent to PM;
- use proper ioctl direction flags (and new numbers) for requests;
- remove some needless header inclusions;
- svrctl is in libc, make its message name reflect this;
- keep backward compatibility: svrctl is part of the userland ABI.

Change-Id: I44902e8d0d11b8ebc1ef3bda94d2202481743c9b
2014-09-29 16:15:21 +00:00
David van Moolenbroek
347cc10a91 VFS/FS: putnode count need not be 64-bit
Change-Id: I49e67438d3f316e0321ac711494e988bb6510679
2014-09-29 15:14:02 +00:00
David van Moolenbroek
63ce03db66 IOCTL requests are unsigned longs now
Issue reported by JD Begin.

Change-Id: I0306d9dc43c36107897c8b73ed340d86a8dcef27
2014-09-29 15:11:01 +00:00
AndrewEdwards
e3fd605f72 Create new colemak minix keymap.
Change-Id: I3464e723bd6bb578f415dfe78540e60b2eefb8b7
2014-09-29 00:39:25 +02:00
Ben Gras
5075cea916 build lua dynamically
. allows modules to be loaded

Fix submitted by Marc Balmer <mbalmer@NetBSD.org>

Change-Id: I6b2d19c2c9b136f0d72d2f714027221c0b86b5ae
2014-09-28 16:31:54 +02:00
Ben Gras
0d9602e04b Import NetBSD legal/COPYRIGHT.
Change-Id: Ic23e5f1902ade92402faa968bb945b7d873aaf6b
2014-09-28 16:28:05 +02:00
Alexandre Beletti
6a76678e59 Import NetBSD games/fish command.
Change-Id: Ie3009121c768fa5e0c50c681b87cde344ae7cfe2
2014-09-25 02:03:28 +02:00
Sky Liu
ca78167b44 Porting grep from NetBSD
Change-Id: I6fa9e3c0a4edc4d3ff292dc5c96ac16b34d7c792
2014-09-24 15:33:57 +02:00
Alexandre Beletti
831337191b Import NetBSD games/snake command.
Change-Id: Ie46c0acc09e5e8079f80301ae3a40172fcfb51dd
2014-09-24 11:58:53 +02:00
David van Moolenbroek
3a40bab785 tests: reenable testisofs
Change-Id: Ic0883f8b487390e34f1a27e324b033a8cbe2cfff
2014-09-18 13:01:13 +00:00
David van Moolenbroek
ef9dc93f44 Clean up obsolete FS support routines
Change-Id: I56d0ab51f32064bb964051732de7e2465dc22b75
2014-09-18 13:01:02 +00:00
David van Moolenbroek
c2f99d7c3a isofs: rename source directory to "isofs"
Change-Id: Ibe630f720b4399e7ebbbd850650036fbaa9cec7b
2014-09-18 13:00:57 +00:00
David van Moolenbroek
edfcb02885 isofs: basic improvements
- fix for "out of extents" panic;
- return ENOENT when a file name does not exist;
- inode count sanity check upon unmount.

Change-Id: Icb97dbaf7c8aec463438f06b341defca357094b2
2014-09-18 13:00:52 +00:00
David van Moolenbroek
e2dc2c8954 isofs: use libdriver
Change-Id: I5ced800eec92f651f31d9c77c3129fe837ca4614
2014-09-18 13:00:47 +00:00
Jean-Baptiste Boric
3e08d38e8e iso9660fs: rewrite ISO 9660 file system server
iso9660fs has been cleaned up and debugged. It now supports:
 * ISO 9660 Level 3,
 * System Use Sharing Protocol (SUSP),
 * Rock Ridge Interchange Protocol (RRIP).

The following Rock Ridge features are supported:
 * POSIX file attributes (PX),
 * POSIX device number (PN),
 * Symbolic links (SL),
 * Alternate file name (NM),
 * Timestamps in 7-byte format (TF).

Change-Id: Ib227411bdda5bc10a957b27ad05fafdc95eca35f
2014-09-18 13:00:42 +00:00
David van Moolenbroek
1858c65d72 Revert "Temporarily disable the is9600 FS server"
This reverts commit ab5c98ee5a.
2014-09-18 12:59:18 +00:00
David van Moolenbroek
8ca6466a71 writeisofs: set file struct version field to one
Dictated by the spec and correctly flagged by the new isofs code.

Change-Id: Ie155c30b6a53e40ec42066af0adbcdbf457e5620
2014-09-18 12:46:29 +00:00
David van Moolenbroek
30d9b70391 PFS: rewrite, restyle
- remove the buffer pool, inode bitmap, and inode hash table, and
  simplify the code accordingly;
- use theoretically slightly more optimal buffer management;
- put the entire source in one file, instead of having many files
  with one or two functions each;
- convert the code to KNF style.

Change-Id: Ib8f6f0bd99fbc6eb9098fba718e71b8e560783d9
2014-09-18 12:46:28 +00:00
David van Moolenbroek
f859061eaf PFS: use libfsdriver
In order to avoid creating libfsdriver exceptions, two changes to VFS
are necessary:

- the returned position field for reads/writes is no longer abused to
  return the new pipe size; VFS is perfectly capable of updating the
  size itself;
- during system startup, PFS is now sent a mount request, just like all
  other file systems.

In proper "two steps forward, one step back" fashion, the latter point
has the consequence that PFS can no longer drop its privileges at
startup.  This is probably best resolved with a more general solution
for all boot image system services.  The upside is that PFS no longer
needs to be linked with libc.

Change-Id: I92e2410cdb0d93d0e6107bae10bc08efc2dbb8b3
2014-09-18 12:46:28 +00:00
David van Moolenbroek
2e89653e65 libc: make socketpair(3) use the right device
UDS expects the device number of the actual socket, not the device on
which the socket happens to reside.  The code worked only because PFS
returned the same value in the st_dev stat field, which it will have
to continue doing for a while now.

Change-Id: I426d38a86a96307ff6e6ed8099d37dae02d6bf2b
2014-09-18 12:46:28 +00:00
David van Moolenbroek
970d95ecd5 ext2: use libfsdriver
- fix panic on truncating files with holes;
- remove block-based readahead, to match MFS.

Change-Id: I385552f8019e9c013a6cb937bcc8e4e7181a4a50
2014-09-18 12:46:27 +00:00
David van Moolenbroek
ccaeedb267 MFS: use libfsdriver
Change-Id: Ib658c7dea47b81a417755b0554a75288117b431a
2014-09-18 12:46:27 +00:00
David van Moolenbroek
ad80a203db Move clock_time into libsys
Change-Id: Ibc5034617e6f6581de7c4a166ca075b3c357fa82
2014-09-18 12:46:26 +00:00
David van Moolenbroek
0dc5c83ec2 libvtreefs: use libfsdriver
Change-Id: I0e6446bd0ccc3b89edc237be441ebfd92585f352
2014-09-18 12:46:26 +00:00
David van Moolenbroek
81db4f2cff libpuffs: use libfsdriver
Change-Id: I26651578066e1098dc275a9cfbe5710870a13811
2014-09-18 12:46:25 +00:00
David van Moolenbroek
a99c939dee libsffs: use libfsdriver
Change-Id: Id8377873455771c614371e115643cd906d05f12c
2014-09-18 12:46:25 +00:00
David van Moolenbroek
ebd3c0673d libminixfs: add block I/O routines
The new functionality aims to save each file system server from having
to implement its own block I/O routines just so that it can serve as a
root file system.  The new source file (bio.c) lists the requirements
that file system servers have to fulfill in order to use the routines.

Change-Id: Ia0190fd5c30e8c2097ed8f4b0e3ccde1827e0b92
2014-09-18 12:46:25 +00:00
David van Moolenbroek
c5beebb68d libminixfs: do not make fs_sync upcalls
The file system may not be expecting these upcalls at arbitrary
moments, while they serve only as a performance optimization anyway.

Change-Id: I0748fd1f6c2645ddbb64466093ee36025aac45e0
2014-09-18 12:46:24 +00:00
David van Moolenbroek
35118b0a91 test72: fix mock bdev functions
The minixfs library only ever submits vector elements (and reads) of
the system page size. The test implementation was expecting vector
elements (and reads) of the file system block size. The resulting
mismatch caused I/O to fail in various ways, even though this did not
have an effect on the actual test.

Change-Id: I02f4a3efcd4a32916435d82c7d5798e6b78f0a27
2014-09-18 12:46:24 +00:00
David van Moolenbroek
f018897664 test72: fix premature block size update
Updating the current block size before flushing the cache, which still
contained blocks with the old block size, resulted in triggering an
assert on position alignment.

Change-Id: I7a83f3d3bc57bafc08aa6c8df64fbf978273bbfd
2014-09-18 12:46:23 +00:00
David van Moolenbroek
89c9de7d09 Add libfsdriver: a library to drive file systems
This library provides new abstractions for the upper (VFS) side of
file system services, and should be used for all file system service
implementations from now on.  It provides the following functionality:

  - a function call table abstraction, hiding the details of the
    VFS-FS protocol with simple parameters;
  - a (currently limited) number of per-function steps required for
    all file system implementations, such as copying in and out path
    names and result buffers;
  - a default implementation for multicomponent path lookups, such
    that the file system merely has to implement resolution of single
    components at a time;
  - an abstraction for copying data from and to the file system, which
    allows transparent intraprocess copying as required for the lookup
    implementation;
  - a set of functions to simplify getdents implementations.

The message loop provided by the library is currently for use by
single-threaded file system implementations only.  Multithreaded file
system services may use the more low-level message processing
functionality.

Protocol-level optimizations such as including names in protocol
messages may be hidden entirely in this library.  In addition, in the
future, the lookup implementation may be replaced by a single-
component lookup VFS/FS protocol request as part of a VFS name cache
implementation; this, too, can be hidden entirely in this library.

Change-Id: Ib34f0d0e021dfa3426ce8826efcf3eaa94d3ef3e
2014-09-18 12:46:23 +00:00
David van Moolenbroek
e7b4aa7d99 VFS: provide correct root directory for lookups
This fixes a VFS panic and a chroot(2) security hole.

Change-Id: Ifd1923f886501cf3a73277aab89db974798c47dc
2014-09-18 12:46:23 +00:00
David van Moolenbroek
71cd1dd4b9 VFS: do not call REQ_FLUSH on the root file system
Change-Id: I15d29a6f3d198e604ea7f7a9db600d6d18b6994b
2014-09-18 12:46:22 +00:00
3276 changed files with 688489 additions and 119691 deletions

View File

@@ -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
View 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
View 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

File diff suppressed because it is too large Load Diff

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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

32
bin/csh/USD.doc/tabs Normal file
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

1401
bin/csh/csh.c Normal file

File diff suppressed because it is too large Load Diff

559
bin/csh/csh.h Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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 = &paraml1;
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(&paraml1);
t = syntax(paraml1.next, &paraml1, 0);
if (seterr)
stderror(ERR_OLD);
execute(t, -1, NULL, NULL);
freelex(&paraml1), 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
View 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
View 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

File diff suppressed because it is too large Load Diff

923
bin/csh/glob.c Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

407
bin/csh/misc.c Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

104
bin/csh/proc.h Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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>

View 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 .

View 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
View 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
View 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
View 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>

View File

@@ -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
View 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
View 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
View 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
View 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 */
}

View File

@@ -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

View File

@@ -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__ */

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
/*

View File

@@ -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)
{

View File

@@ -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>

View File

@@ -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}"
}
#

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -1 +0,0 @@
set autoindent autowrite report=2 showmatch

View File

@@ -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
View 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
View 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
View 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).

View File

@@ -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
View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
View File

@@ -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" ]

View File

@@ -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
View 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
View 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