diff options
Diffstat (limited to 'usr.bin')
| -rw-r--r-- | usr.bin/pkill/Makefile | 13 | ||||
| -rw-r--r-- | usr.bin/pkill/pkill.1 | 197 | ||||
| -rw-r--r-- | usr.bin/pkill/pkill.c | 541 | ||||
| -rw-r--r-- | usr.bin/sort/Makefile | 7 | ||||
| -rw-r--r-- | usr.bin/sort/append.c | 205 | ||||
| -rw-r--r-- | usr.bin/sort/extern.h | 69 | ||||
| -rw-r--r-- | usr.bin/sort/fields.c | 339 | ||||
| -rw-r--r-- | usr.bin/sort/files.c | 372 | ||||
| -rw-r--r-- | usr.bin/sort/fsort.c | 358 | ||||
| -rw-r--r-- | usr.bin/sort/fsort.h | 77 | ||||
| -rw-r--r-- | usr.bin/sort/init.c | 355 | ||||
| -rw-r--r-- | usr.bin/sort/msort.c | 390 | ||||
| -rw-r--r-- | usr.bin/sort/pathnames.h | 41 | ||||
| -rw-r--r-- | usr.bin/sort/sort.1 | 441 | ||||
| -rw-r--r-- | usr.bin/sort/sort.c | 332 | ||||
| -rw-r--r-- | usr.bin/sort/sort.h | 149 | ||||
| -rw-r--r-- | usr.bin/sort/tmp.c | 84 | ||||
| -rw-r--r-- | usr.bin/stat/Makefile | 8 | ||||
| -rw-r--r-- | usr.bin/stat/stat.1 | 434 | ||||
| -rw-r--r-- | usr.bin/stat/stat.c | 986 | ||||
| -rw-r--r-- | usr.bin/units/Makefile | 9 | ||||
| -rw-r--r-- | usr.bin/units/README | 18 | ||||
| -rw-r--r-- | usr.bin/units/pathnames.h | 33 | ||||
| -rw-r--r-- | usr.bin/units/units.1 | 124 | ||||
| -rw-r--r-- | usr.bin/units/units.c | 706 | ||||
| -rw-r--r-- | usr.bin/units/units.lib | 610 | ||||
| -rw-r--r-- | usr.bin/whereis/whereis.1 | 75 | ||||
| -rw-r--r-- | usr.bin/whereis/whereis.c | 138 |
28 files changed, 0 insertions, 7111 deletions
diff --git a/usr.bin/pkill/Makefile b/usr.bin/pkill/Makefile deleted file mode 100644 index 52aed1ae9a3c..000000000000 --- a/usr.bin/pkill/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# $NetBSD$ - -PROG= pkill -SRCS= pkill.c -MAN= pkill.1 - -LDADD+= -lkvm -DPADD+= ${LIBKVM} - -LINKS+= ${BINDIR}/pkill ${BINDIR}/pgrep -MLINKS+=pkill.1 pgrep.1 - -.include <bsd.prog.mk> diff --git a/usr.bin/pkill/pkill.1 b/usr.bin/pkill/pkill.1 deleted file mode 100644 index aeda347cf2a9..000000000000 --- a/usr.bin/pkill/pkill.1 +++ /dev/null @@ -1,197 +0,0 @@ -.\" $NetBSD: pkill.1,v 1.7 2002/03/06 12:03:48 ad Exp $ -.\" -.\" Copyright (c) 2002 The NetBSD Foundation, Inc. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to The NetBSD Foundation -.\" by Andrew Doran. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the NetBSD -.\" Foundation, Inc. and its contributors. -.\" 4. Neither the name of The NetBSD Foundation 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 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. -.\" -.Dd March 1, 2002 -.Dt PKILL 1 -.Os -.Sh NAME -.Nm pkill -.Nd find or signal processes by name -.Sh SYNOPSIS -.Nm pgrep -.Op Fl flnvx -.Op Fl G Ar gid -.Op Fl P Ar ppid -.Op Fl U Ar uid -.Op Fl d Ar delim -.Op Fl g Ar pgrp -.Op Fl s Ar sid -.Op Fl t Ar tty -.Op Fl u Ar euid -.Op Ar pattern Op ... -.Nm pkill -.Op Fl signal -.Op Fl fnvx -.Op Fl G Ar gid -.Op Fl P Ar ppid -.Op Fl U Ar uid -.Op Fl g Ar pgrp -.Op Fl s Ar sid -.Op Fl t Ar tty -.Op Fl u Ar euid -.Op Ar pattern Op ... -.Sh DESCRIPTION -The -.Nm pgrep -command searches the process table on the running system and prints the -process IDs of all processes that match the criteria given on the command -line. -.Pp -The -.Nm pkill -command searches the process table on the running system and signals all -processes that match the criteria given on the command line. -.Pp -The following options are available: -.Bl -tag -width xxxxxxxx -.It Fl G Ar gid -Restrict matches to processes with a real group ID in the comma-separated -list -.Ar gid . -.It Fl P Ar ppid -Restrict matches to processes with a parent process ID in the -comma-separated list -.Ar ppid . -.It Fl U Ar uid -Restrict matches to processes with a real user ID in the comma-separated -list -.Ar uid . -.It Fl d Ar delim -Specify a delimiter to be printed between each process ID. -The default is a newline. -This option can only be used with the -.Nm pgrep -command. -.It Fl f -Match against full argument lists. -The default is to match against process names. -.It Fl g Ar pgrp -Restrict matches to processes with a process group ID in the comma-separated -list -.Ar pgrp . -The value zero is taken to mean the process group ID of the running -.Nm pgrep -or -.Nm pkill -command. -.It Fl l -Long output. -Print the process name in addition to the process ID for each matching -process. -If used in conjunction with -.Fl f , -print the process ID and the full argument list for each matching process. -This option can only be used with the -.Nm pgrep -command. -.It Fl n -Match only the most recently created process, if any. -.It Fl s Ar sid -Restrict matches to processes with a session ID in the comma-separated -list -.Ar sid . -The value zero is taken to mean the session ID of the running -.Nm pgrep -or -.Nm pkill -command. -.It Fl t Ar tty -Restrict matches to processes associated with a terminal in the -comma-separated list -.Ar tty . -Terminal names may be of the form -.Sq ttyxx -or the shortened form -.Sq xx . -A single dash (`-') matches processes not associated with a terminal. -.It Fl u Ar euid -Restrict matches to processes with an effective user ID in the -comma-separated list -.Ar euid . -.It Fl v -Reverse the sense of the matching; display processes that do not match the -given criteria. -.It Fl x -Require an exact match of the process name, or argument list if -.Fl f -is given. -The default is to match any substring. -.It Fl signal -A non-negative decimal number or symbolic signal name specifying the signal -to be sent instead of the default TERM. -This option is valid only when given as the first argument to -.Nm pkill . -.El -.Pp -Note that a running -.Nm pgrep -or -.Nm pkill -process will never consider itself nor system processes (kernel threads) as -a potential match. -.Sh EXIT STATUS -.Nm pgrep -and -.Nm pkill -return one of the following values upon exit: -.Bl -tag -width foo -.It 0 -One or more processes were matched. -.It 1 -No processes were matched. -.It 2 -Invalid options were specified on the command line. -.It 3 -An internal error occurred. -.El -.Sh SEE ALSO -.Xr kill 1 , -.Xr ps 1 , -.Xr kill 2 , -.Xr sigaction 2 , -.Xr re_format 7 , -.Xr signal 7 -.Sh HISTORY -.Nm pkill -and -.Nm pgrep -first appeared in -.Nx 1.6 . -They are modelled after utilities of the same name that appeared in Sun -Solaris 7. -.Sh AUTHORS -.An Andrew Doran -.Aq ad@NetBSD.org . diff --git a/usr.bin/pkill/pkill.c b/usr.bin/pkill/pkill.c deleted file mode 100644 index 884173ed4b0a..000000000000 --- a/usr.bin/pkill/pkill.c +++ /dev/null @@ -1,541 +0,0 @@ -/* $NetBSD: pkill.c,v 1.6 2004/01/06 07:35:58 itojun Exp $ */ - -/*- - * Copyright (c) 2002 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Andrew Doran. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation 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 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: pkill.c,v 1.6 2004/01/06 07:35:58 itojun Exp $"); -#endif /* !lint */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/sysctl.h> -#include <sys/proc.h> -#include <sys/queue.h> -#include <sys/stat.h> - -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> -#include <regex.h> -#include <ctype.h> -#include <kvm.h> -#include <err.h> -#include <pwd.h> -#include <grp.h> -#include <errno.h> - -#define STATUS_MATCH 0 -#define STATUS_NOMATCH 1 -#define STATUS_BADUSAGE 2 -#define STATUS_ERROR 3 - -enum listtype { - LT_GENERIC, - LT_USER, - LT_GROUP, - LT_TTY, - LT_PGRP, - LT_SID -}; - -struct list { - SLIST_ENTRY(list) li_chain; - long li_number; -}; - -SLIST_HEAD(listhead, list); - -struct kinfo_proc2 *plist; -char *selected; -char *delim = "\n"; -int nproc; -int pgrep; -int signum = SIGTERM; -int newest; -int inverse; -int longfmt; -int matchargs; -int fullmatch; -kvm_t *kd; -pid_t mypid; - -struct listhead euidlist = SLIST_HEAD_INITIALIZER(list); -struct listhead ruidlist = SLIST_HEAD_INITIALIZER(list); -struct listhead rgidlist = SLIST_HEAD_INITIALIZER(list); -struct listhead pgrplist = SLIST_HEAD_INITIALIZER(list); -struct listhead ppidlist = SLIST_HEAD_INITIALIZER(list); -struct listhead tdevlist = SLIST_HEAD_INITIALIZER(list); -struct listhead sidlist = SLIST_HEAD_INITIALIZER(list); - -int main(int, char **); -void usage(void); -void killact(struct kinfo_proc2 *); -void grepact(struct kinfo_proc2 *); -void makelist(struct listhead *, enum listtype, char *); - -int -main(int argc, char **argv) -{ - extern char *optarg; - extern int optind; - char buf[_POSIX2_LINE_MAX], *mstr, **pargv, *p, *q; - int i, j, ch, bestidx, rv, criteria; - void (*action)(struct kinfo_proc2 *); - struct kinfo_proc2 *kp; - struct list *li; - u_int32_t bestsec, bestusec; - regex_t reg; - regmatch_t regmatch; - - if (strcmp(getprogname(), "pgrep") == 0) { - action = grepact; - pgrep = 1; - } else { - action = killact; - p = argv[1]; - - if (argc > 1 && p[0] == '-') { - p++; - i = (int)strtol(p, &q, 10); - if (*q == '\0') { - signum = i; - argv++; - argc--; - } else { - if (strncasecmp(p, "sig", 3) == 0) - p += 3; - for (i = 1; i < NSIG; i++) - if (strcasecmp(sys_signame[i], p) == 0) - break; - if (i != NSIG) { - signum = i; - argv++; - argc--; - } - } - } - } - - criteria = 0; - - while ((ch = getopt(argc, argv, "G:P:U:d:fg:lns:t:u:vx")) != -1) - switch (ch) { - case 'G': - makelist(&rgidlist, LT_GROUP, optarg); - criteria = 1; - break; - case 'P': - makelist(&ppidlist, LT_GENERIC, optarg); - criteria = 1; - break; - case 'U': - makelist(&ruidlist, LT_USER, optarg); - criteria = 1; - break; - case 'd': - if (!pgrep) - usage(); - delim = optarg; - break; - case 'f': - matchargs = 1; - break; - case 'g': - makelist(&pgrplist, LT_PGRP, optarg); - criteria = 1; - break; - case 'l': - if (!pgrep) - usage(); - longfmt = 1; - break; - case 'n': - newest = 1; - criteria = 1; - break; - case 's': - makelist(&sidlist, LT_SID, optarg); - criteria = 1; - break; - case 't': - makelist(&tdevlist, LT_TTY, optarg); - criteria = 1; - break; - case 'u': - makelist(&euidlist, LT_USER, optarg); - criteria = 1; - break; - case 'v': - inverse = 1; - break; - case 'x': - fullmatch = 1; - break; - default: - usage(); - /* NOTREACHED */ - } - - argc -= optind; - argv += optind; - if (argc != 0) - criteria = 1; - if (!criteria) - usage(); - - mypid = getpid(); - - /* - * Retrieve the list of running processes from the kernel. - */ - kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, buf); - if (kd == NULL) - errx(STATUS_ERROR, "kvm_openfiles(): %s", buf); - - plist = kvm_getproc2(kd, KERN_PROC_ALL, 0, sizeof(*plist), &nproc); - if (plist == NULL) - errx(STATUS_ERROR, "kvm_getproc2() failed"); - - /* - * Allocate memory which will be used to keep track of the - * selection. - */ - if ((selected = malloc(nproc)) == NULL) - errx(STATUS_ERROR, "memory allocation failure"); - memset(selected, 0, nproc); - - /* - * Refine the selection. - */ - for (; *argv != NULL; argv++) { - if ((rv = regcomp(®, *argv, REG_EXTENDED)) != 0) { - regerror(rv, ®, buf, sizeof(buf)); - errx(STATUS_BADUSAGE, "bad expression: %s", buf); - } - - for (i = 0, kp = plist; i < nproc; i++, kp++) { - if ((kp->p_flag & P_SYSTEM) != 0 || kp->p_pid == mypid) - continue; - - if (matchargs) { - if ((pargv = kvm_getargv2(kd, kp, 0)) == NULL) - continue; - - j = 0; - while (j < sizeof(buf) && *pargv != NULL) { - j += snprintf(buf + j, sizeof(buf) - j, - pargv[1] != NULL ? "%s " : "%s", - pargv[0]); - pargv++; - } - - mstr = buf; - } else - mstr = kp->p_comm; - - rv = regexec(®, mstr, 1, ®match, 0); - if (rv == 0) { - if (fullmatch) { - if (regmatch.rm_so == 0 && - regmatch.rm_eo == strlen(mstr)) - selected[i] = 1; - } else - selected[i] = 1; - } else if (rv != REG_NOMATCH) { - regerror(rv, ®, buf, sizeof(buf)); - errx(STATUS_ERROR, "regexec(): %s", buf); - } - } - - regfree(®); - } - - for (i = 0, kp = plist; i < nproc; i++, kp++) { - if ((kp->p_flag & P_SYSTEM) != 0) - continue; - - SLIST_FOREACH(li, &ruidlist, li_chain) - if (kp->p_ruid == (uid_t)li->li_number) - break; - if (SLIST_FIRST(&ruidlist) != NULL && li == NULL) { - selected[i] = 0; - continue; - } - - SLIST_FOREACH(li, &rgidlist, li_chain) - if (kp->p_rgid == (gid_t)li->li_number) - break; - if (SLIST_FIRST(&rgidlist) != NULL && li == NULL) { - selected[i] = 0; - continue; - } - - SLIST_FOREACH(li, &euidlist, li_chain) - if (kp->p_uid == (uid_t)li->li_number) - break; - if (SLIST_FIRST(&euidlist) != NULL && li == NULL) { - selected[i] = 0; - continue; - } - - SLIST_FOREACH(li, &ppidlist, li_chain) - if (kp->p_ppid == (uid_t)li->li_number) - break; - if (SLIST_FIRST(&ppidlist) != NULL && li == NULL) { - selected[i] = 0; - continue; - } - - SLIST_FOREACH(li, &pgrplist, li_chain) - if (kp->p__pgid == (uid_t)li->li_number) - break; - if (SLIST_FIRST(&pgrplist) != NULL && li == NULL) { - selected[i] = 0; - continue; - } - - SLIST_FOREACH(li, &tdevlist, li_chain) { - if (li->li_number == -1 && - (kp->p_flag & P_CONTROLT) == 0) - break; - if (kp->p_tdev == (uid_t)li->li_number) - break; - } - if (SLIST_FIRST(&tdevlist) != NULL && li == NULL) { - selected[i] = 0; - continue; - } - - SLIST_FOREACH(li, &sidlist, li_chain) - if (kp->p_sid == (uid_t)li->li_number) - break; - if (SLIST_FIRST(&sidlist) != NULL && li == NULL) { - selected[i] = 0; - continue; - } - - if (argc == 0) - selected[i] = 1; - } - - if (newest) { - bestsec = 0; - bestusec = 0; - bestidx = -1; - - for (i = 0, kp = plist; i < nproc; i++, kp++) { - if (!selected[i]) - continue; - - if (kp->p_ustart_sec > bestsec || - (kp->p_ustart_sec == bestsec - && kp->p_ustart_usec > bestusec)) { - bestsec = kp->p_ustart_sec; - bestusec = kp->p_ustart_usec; - bestidx = i; - } - } - - memset(selected, 0, nproc); - if (bestidx != -1) - selected[bestidx] = 1; - } - - /* - * Take the appropriate action for each matched process, if any. - */ - for (i = 0, rv = 0, kp = plist; i < nproc; i++, kp++) { - if (kp->p_pid == mypid) - continue; - if (selected[i]) { - if (inverse) - continue; - } else if (!inverse) - continue; - - if ((kp->p_flag & P_SYSTEM) != 0) - continue; - - rv = 1; - (*action)(kp); - } - - exit(rv ? STATUS_MATCH : STATUS_NOMATCH); -} - -void -usage(void) -{ - const char *ustr; - - if (pgrep) - ustr = "[-flnvx] [-d delim]"; - else - ustr = "[-signal] [-fnvx]"; - - fprintf(stderr, - "usage: %s %s [-G gid] [-P ppid] [-U uid] [-g pgrp] [-s sid]\n" - " [-t tty] [-u euid] pattern ...\n", getprogname(), - ustr); - - exit(STATUS_ERROR); -} - -void -killact(struct kinfo_proc2 *kp) -{ - - if (kill(kp->p_pid, signum) == -1) - err(STATUS_ERROR, "signalling pid %d", (int)kp->p_pid); -} - -void -grepact(struct kinfo_proc2 *kp) -{ - char **argv; - - if (longfmt && matchargs) { - if ((argv = kvm_getargv2(kd, kp, 0)) == NULL) - return; - - printf("%d ", (int)kp->p_pid); - for (; *argv != NULL; argv++) { - printf("%s", *argv); - if (argv[1] != NULL) - putchar(' '); - } - } else if (longfmt) - printf("%d %s", (int)kp->p_pid, kp->p_comm); - else - printf("%d", (int)kp->p_pid); - - printf("%s", delim); -} - -void -makelist(struct listhead *head, enum listtype type, char *src) -{ - struct list *li; - struct passwd *pw; - struct group *gr; - struct stat st; - char *sp, *p, buf[MAXPATHLEN]; - int empty; - - empty = 1; - - while ((sp = strsep(&src, ",")) != NULL) { - if (*sp == '\0') - usage(); - - if ((li = malloc(sizeof(*li))) == NULL) - errx(STATUS_ERROR, "memory allocation failure"); - SLIST_INSERT_HEAD(head, li, li_chain); - empty = 0; - - li->li_number = (uid_t)strtol(sp, &p, 0); - if (*p == '\0') { - switch (type) { - case LT_PGRP: - if (li->li_number == 0) - li->li_number = getpgrp(); - break; - case LT_SID: - if (li->li_number == 0) - li->li_number = getsid(mypid); - break; - case LT_TTY: - usage(); - default: - break; - } - continue; - } - - switch (type) { - case LT_USER: - if ((pw = getpwnam(sp)) == NULL) - errx(STATUS_BADUSAGE, "unknown user `%s'", - optarg); - li->li_number = pw->pw_uid; - break; - case LT_GROUP: - if ((gr = getgrnam(sp)) == NULL) - errx(STATUS_BADUSAGE, "unknown group `%s'", - optarg); - li->li_number = gr->gr_gid; - break; - case LT_TTY: - if (strcmp(sp, "-") == 0) { - li->li_number = -1; - break; - } else if (strcmp(sp, "co") == 0) - p = "console"; - else if (strncmp(sp, "tty", 3) == 0) - p = sp; - else - p = NULL; - - if (p == NULL) - snprintf(buf, sizeof(buf), "/dev/tty%s", sp); - else - snprintf(buf, sizeof(buf), "/dev/%s", p); - - if (stat(buf, &st) < 0) { - if (errno == ENOENT) - errx(STATUS_BADUSAGE, - "no such tty: `%s'", sp); - err(STATUS_ERROR, "stat(%s)", sp); - } - - if ((st.st_mode & S_IFCHR) == 0) - errx(STATUS_BADUSAGE, "not a tty: `%s'", sp); - - li->li_number = st.st_rdev; - break; - default: - usage(); - }; - } - - if (empty) - usage(); -} diff --git a/usr.bin/sort/Makefile b/usr.bin/sort/Makefile deleted file mode 100644 index d7259ba3e4f6..000000000000 --- a/usr.bin/sort/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# $NetBSD: Makefile,v 1.3 2001/01/08 19:16:49 jdolecek Exp $ -# from: @(#)Makefile 8.1 (Berkeley) 6/6/93 - -PROG= sort -SRCS= append.c fields.c files.c fsort.c init.c msort.c sort.c tmp.c - -.include <bsd.prog.mk> diff --git a/usr.bin/sort/append.c b/usr.bin/sort/append.c deleted file mode 100644 index d24b9fea3a7f..000000000000 --- a/usr.bin/sort/append.c +++ /dev/null @@ -1,205 +0,0 @@ -/* $NetBSD: append.c,v 1.9 2001/01/18 20:59:43 jdolecek Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Peter McIlroy. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "sort.h" - -#ifndef lint -__RCSID("$NetBSD: append.c,v 1.9 2001/01/18 20:59:43 jdolecek Exp $"); -__SCCSID("@(#)append.c 8.1 (Berkeley) 6/6/93"); -#endif /* not lint */ - -#include <stdlib.h> -#include <string.h> - -#define OUTPUT { \ - if ((n = cpos - ppos) > 1) { \ - for (; ppos < cpos; ++ppos) \ - *ppos -= odepth; \ - ppos -= n; \ - if (stable_sort) \ - sradixsort(ppos, n, wts1, REC_D); \ - else \ - radixsort(ppos, n, wts1, REC_D); \ - for (; ppos < cpos; ppos++) { \ - prec = (const RECHEADER *) (*ppos - sizeof(TRECHEADER));\ - put(prec, fp); \ - } \ - } else put(prec, fp); \ -} - -/* - * copy sorted lines to output; check for uniqueness - */ -void -append(keylist, nelem, depth, fp, put, ftbl) - const u_char **keylist; - int nelem; - int depth; - FILE *fp; - put_func_t put; - struct field *ftbl; -{ - u_char *wts, *wts1; - int n, odepth; - const u_char **cpos, **ppos, **lastkey; - const u_char *cend, *pend, *start; - const struct recheader *crec, *prec; - - if (*keylist == '\0' && UNIQUE) - return; - wts1 = wts = ftbl[0].weights; - if ((!UNIQUE) && SINGL_FLD) { - if ((ftbl[0].flags & F) && (ftbl[0].flags & R)) - wts1 = Rascii; - else if (ftbl[0].flags & F) - wts1 = ascii; - odepth = depth; - } - lastkey = keylist + nelem; - depth += sizeof(TRECHEADER); - if (SINGL_FLD && (UNIQUE || wts1 != wts)) { - ppos = keylist; - prec = (const RECHEADER *) (*ppos - depth); - if (UNIQUE) - put(prec, fp); - for (cpos = &keylist[1]; cpos < lastkey; cpos++) { - crec = (const RECHEADER *) (*cpos - depth); - if (crec->length == prec->length) { - /* - * Set pend and cend so that trailing NUL and - * record separator is ignored. - */ - pend = (const u_char *) &prec->data + prec->length - 2; - cend = (const u_char *) &crec->data + crec->length - 2; - for (start = *cpos; cend >= start; cend--) { - if (wts[*cend] != wts[*pend]) - break; - pend--; - } - if (pend + 1 != *ppos) { - if (!UNIQUE) { - OUTPUT; - } else - put(crec, fp); - ppos = cpos; - prec = crec; - } - } else { - if (!UNIQUE) { - OUTPUT; - } else - put(crec, fp); - ppos = cpos; - prec = crec; - } - } - if (!UNIQUE) { OUTPUT; } - } else if (UNIQUE) { - ppos = keylist; - prec = (const RECHEADER *) (*ppos - depth); - put(prec, fp); - for (cpos = &keylist[1]; cpos < lastkey; cpos++) { - crec = (const RECHEADER *) (*cpos - depth); - if (crec->offset == prec->offset) { - /* - * Set pend and cend so that trailing NUL and - * record separator is ignored. - */ - pend = (const u_char *) &prec->data + prec->offset - 2; - cend = (const u_char *) &crec->data + crec->offset - 2; - for (start = *cpos; cend >= start; cend--) { - if (wts[*cend] != wts[*pend]) - break; - pend--; - } - if (pend + 1 != *ppos) { - ppos = cpos; - prec = crec; - put(prec, fp); - } - } else { - ppos = cpos; - prec = crec; - put(prec, fp); - } - } - } else for (cpos = keylist; cpos < lastkey; cpos++) { - crec = (const RECHEADER *) (*cpos - depth); - put(crec, fp); - } -} - -/* - * output the already sorted eol bin. - */ -void -rd_append(binno, infl0, nfiles, outfp, buffer, bufend) - u_char *buffer; - int infl0; - int binno, nfiles; - FILE *outfp; - u_char *bufend; -{ - RECHEADER *rec; - - rec = (RECHEADER *) buffer; - if (!getnext(binno, infl0, NULL, nfiles, - (RECHEADER *) buffer, bufend, 0)) { - putline(rec, outfp); - while (getnext(binno, infl0, NULL, nfiles, (RECHEADER *) buffer, - bufend, 0) == 0) { - if (!UNIQUE) - putline(rec, outfp); - } - } -} - -/* - * append plain text--used after sorting the biggest bin. - */ -void -concat(a, b) - FILE *a, *b; -{ - int nread; - char buffer[4096]; - - rewind(b); - while ((nread = fread(buffer, 1, 4096, b)) > 0) - EWRITE(buffer, 1, nread, a); -} diff --git a/usr.bin/sort/extern.h b/usr.bin/sort/extern.h deleted file mode 100644 index cdfb9fe2bd90..000000000000 --- a/usr.bin/sort/extern.h +++ /dev/null @@ -1,69 +0,0 @@ -/* $NetBSD: extern.h,v 1.5 2001/01/12 19:31:25 jdolecek Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Peter McIlroy. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)extern.h 8.1 (Berkeley) 6/6/93 - */ - -void append __P((const u_char **, int, int, FILE *, - void (*)(const RECHEADER *, FILE *), struct field *)); -void concat __P((FILE *, FILE *)); -length_t enterkey __P((RECHEADER *, DBT *, int, struct field *)); -void fixit __P((int *, char **)); -void fldreset __P((struct field *)); -FILE *ftmp __P((void)); -void fmerge __P((int, int, struct filelist *, int, - get_func_t, FILE *, put_func_t, struct field *)); -void fsort __P((int, int, int, struct filelist *, int, FILE *, - struct field *)); -int geteasy __P((int, int, struct filelist *, - int, RECHEADER *, u_char *, struct field *)); -int getnext __P((int, int, struct filelist *, - int, RECHEADER *, u_char *, struct field *)); -int makekey __P((int, int, struct filelist *, - int, RECHEADER *, u_char *, struct field *)); -int makeline __P((int, int, struct filelist *, - int, RECHEADER *, u_char *, struct field *)); -void merge __P((int, int, get_func_t, FILE *, put_func_t, struct field *)); -void num_init __P((void)); -void onepass __P((const u_char **, int, long, long *, u_char *, FILE *)); -int optval __P((int, int)); -void order __P((struct filelist *, get_func_t, struct field *)); -void putline __P((const RECHEADER *, FILE *)); -void putrec __P((const RECHEADER *, FILE *)); -void rd_append __P((int, int, int, FILE *, u_char *, u_char *)); -int setfield __P((const char *, struct field *, int)); -void settables __P((int)); diff --git a/usr.bin/sort/fields.c b/usr.bin/sort/fields.c deleted file mode 100644 index 175b87fb1fba..000000000000 --- a/usr.bin/sort/fields.c +++ /dev/null @@ -1,339 +0,0 @@ -/* $NetBSD: fields.c,v 1.9 2001/02/19 19:52:27 jdolecek Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Peter McIlroy. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* Subroutines to generate sort keys. */ - -#include "sort.h" - -#ifndef lint -__RCSID("$NetBSD: fields.c,v 1.9 2001/02/19 19:52:27 jdolecek Exp $"); -__SCCSID("@(#)fields.c 8.1 (Berkeley) 6/6/93"); -#endif /* not lint */ - -#define blancmange(ptr) { \ - if (BLANK & d_mask[*(ptr)]) \ - while (BLANK & d_mask[*(++(ptr))]); \ -} - -#define NEXTCOL(pos) { \ - if (!SEP_FLAG) \ - while (BLANK & l_d_mask[*(++pos)]); \ - while (!((FLD_D | REC_D_F) & l_d_mask[*++pos])); \ -} - -static u_char *enterfield __P((u_char *, u_char *, struct field *, int)); -static u_char *number __P((u_char *, u_char *, u_char *, u_char *, int)); - -extern struct coldesc clist[(ND+1)*2]; -extern int ncols; - -#define DECIMAL '.' -#define OFFSET 128 - -u_char TENS[10]; /* TENS[0] = REC_D <= 128 ? 130 - '0' : 2 -'0'... */ -u_char NEGTENS[10]; /* NEGTENS[0] = REC_D <= 128 ? 126 + '0' : 252 +'0' */ -u_char *OFF_TENS, *OFF_NTENS; /* TENS - '0', NEGTENS - '0' */ -u_char fnum[NBINS], rnum[NBINS]; - -/* - * constructs sort key with leading recheader, followed by the key, - * followed by the original line. - */ -length_t -enterkey(keybuf, line, size, fieldtable) - RECHEADER *keybuf; /* pointer to start of key */ - DBT *line; - int size; - struct field fieldtable[]; -{ - int i; - u_char *l_d_mask; - u_char *lineend, *pos; - u_char *endkey, *keypos; - struct coldesc *clpos; - int col = 1; - struct field *ftpos; - l_d_mask = d_mask; - pos = (u_char *) line->data - 1; - lineend = (u_char *) line->data + line->size-1; - /* don't include rec_delimiter */ - - for (i = 0; i < ncols; i++) { - clpos = clist + i; - for (; (col < clpos->num) && (pos < lineend); col++) { - NEXTCOL(pos); - } - if (pos >= lineend) - break; - clpos->start = SEP_FLAG ? pos + 1 : pos; - NEXTCOL(pos); - clpos->end = pos; - col++; - if (pos >= lineend) { - clpos->end = lineend; - i++; - break; - } - } - for (; i <= ncols; i++) - clist[i].start = clist[i].end = lineend; - if (clist[0].start < (u_char *) line->data) - clist[0].start++; - - keypos = keybuf->data; - endkey = (u_char *) keybuf + size - line->size; - for (ftpos = fieldtable + 1; ftpos->icol.num; ftpos++) - if ((keypos = enterfield(keypos, endkey, ftpos, - fieldtable->flags)) == NULL) - return (1); - - keybuf->offset = keypos - keybuf->data; - keybuf->length = keybuf->offset + line->size; - if (keybuf->length + sizeof(TRECHEADER) > size) { - /* line too long for buffer */ - return (1); - } - - /* - * Make [s]radixsort() only sort by relevant part of key if: - * 1. we want to choose unique items by relevant field[s] - * 2. we want stable sort and so the items should be sorted only by - * the relevant field[s] - */ - if (UNIQUE || (stable_sort && keybuf->offset < line->size)) - keypos[-1] = REC_D; - - memcpy(keybuf->data + keybuf->offset, line->data, line->size); - return (0); -} - -/* - * constructs a field (as defined by -k) within a key - */ -static u_char * -enterfield(tablepos, endkey, cur_fld, gflags) - struct field *cur_fld; - u_char *tablepos, *endkey; - int gflags; -{ - u_char *start, *end, *lineend, *mask, *lweight; - struct column icol, tcol; - u_int flags; - u_int Rflag; - - icol = cur_fld->icol; - tcol = cur_fld->tcol; - flags = cur_fld->flags; - start = icol.p->start; - lineend = clist[ncols].end; - if (flags & BI) - blancmange(start); - start += icol.indent; - start = min(start, lineend); - - if (!tcol.num) - end = lineend; - else { - if (tcol.indent) { - end = tcol.p->start; - if (flags & BT) - blancmange(end); - end += tcol.indent; - end = min(end, lineend); - } else - end = tcol.p->end; - } - - if (flags & N) { - Rflag = (gflags & R ) ^ (flags & R) ? 1 : 0; - return number(tablepos, endkey, start, end, Rflag); - } - - mask = cur_fld->mask; - lweight = cur_fld->weights; - for (; start < end; start++) - if (mask[*start]) { - if (*start <= 1) { - if (tablepos+2 >= endkey) - return (NULL); - *tablepos++ = lweight[1]; - *tablepos++ = lweight[*start ? 2 : 1]; - } else { - if (tablepos+1 >= endkey) - return (NULL); - *tablepos++ = lweight[*start]; - } - } - *tablepos++ = lweight[0]; - return (tablepos == endkey ? NULL : tablepos); -} - -/* Uses the first bin to assign sign, expsign, 0, and the first - * 61 out of the exponent ( (254 - 3 origins - 4 over/underflows)/4 = 61 ). - * When sorting in forward order: - * use (0-99) -> (130->240) for sorting the mantissa if REC_D <=128; - * else use (0-99)->(2-102). - * If the exponent is >=61, use another byte for each additional 253 - * in the exponent. Cutoff is at 567. - * To avoid confusing the exponent and the mantissa, use a field delimiter - * if the exponent is exactly 61, 61+252, etc--this is ok, since it's the - * only time a field delimiter can come in that position. - * Reverse order is done analagously. - */ - -static u_char * -number(pos, bufend, line, lineend, Rflag) - u_char *line, *pos, *bufend, *lineend; - int Rflag; -{ - int or_sign, parity = 0; - int expincr = 1, exponent = -1; - int bite, expsign = 1, sign = 1; - u_char lastvalue, *nonzero, *tline, *C_TENS; - u_char *nweights; - - if (Rflag) - nweights = rnum; - else - nweights = fnum; - if (pos > bufend - 8) - return (NULL); - /* - * or_sign sets the sort direction: - * (-r: +/-)(sign: +/-)(expsign: +/-) - */ - or_sign = sign ^ expsign ^ Rflag; - blancmange(line); - if (*line == '-') { /* set the sign */ - or_sign ^= 1; - sign = 0; - line++; - } - /* eat initial zeroes */ - for (; *line == '0' && line < lineend; line++) - ; - /* calculate exponents < 0 */ - if (*line == DECIMAL) { - exponent = 1; - while (*++line == '0' && line < lineend) - exponent++; - expincr = 0; - expsign = 0; - } - /* next character better be a digit */ - if (*line < '1' || *line > '9' || line >= lineend) { - *pos++ = nweights[127]; - return (pos); - } - if (expincr) { - for (tline = line-1; *++tline >= '0' && - *tline <= '9' && tline < lineend;) - exponent++; - } - if (exponent > 567) { - *pos++ = nweights[sign ? (expsign ? 254 : 128) - : (expsign ? 0 : 126)]; - warnx("exponent out of bounds"); - return (pos); - } - bite = min(exponent, 61); - *pos++ = nweights[(sign) ? (expsign ? 189+bite : 189-bite) - : (expsign ? 64-bite : 64+bite)]; - if (bite >= 61) { - do { - exponent -= bite; - bite = min(exponent, 254); - *pos++ = nweights[or_sign ? 254-bite : bite]; - } while (bite == 254); - } - C_TENS = or_sign ? OFF_NTENS : OFF_TENS; - for (; line < lineend; line++) { - if (*line >= '0' && *line <= '9') { - if (parity) { - *pos++ = C_TENS[lastvalue] + (or_sign ? - *line - : *line); - if (pos == bufend) - return (NULL); - if (*line != '0' || lastvalue != '0') - nonzero = pos; - } else - lastvalue = *line; - parity ^= 1; - } else if(*line == DECIMAL) { - if(!expincr) /* a decimal already occurred once */ - break; - expincr = 0; - } else - break; - } - if (parity && lastvalue != '0') { - *pos++ = or_sign ? OFF_NTENS[lastvalue] - '0' : - OFF_TENS[lastvalue] + '0'; - } else - pos = nonzero; - if (pos > bufend-1) - return (NULL); - *pos++ = or_sign ? nweights[254] : nweights[0]; - return (pos); -} - -/* This forces a gap around the record delimiter - * Thus fnum has vaues over (0,254) -> ((0,REC_D-1),(REC_D+1,255)); - * rnum over (0,254) -> (255,REC_D+1),(REC_D-1,0)) - */ -void -num_init() -{ - int i; - TENS[0] = REC_D <=128 ? 130 - '0' : 2 - '0'; - NEGTENS[0] = REC_D <=128 ? 126 + '0' : 254 + '0'; - OFF_TENS = TENS - '0'; - OFF_NTENS = NEGTENS - '0'; - for (i = 1; i < 10; i++) { - TENS[i] = TENS[i - 1] + 10; - NEGTENS[i] = NEGTENS[i - 1] - 10; - } - for (i = 0; i < REC_D; i++) { - fnum[i] = i; - rnum[255 - i] = i; - } - for (i = REC_D; i <255; i++) { - fnum[i] = i + 1; - rnum[255 - i] = i - 1; - } -} diff --git a/usr.bin/sort/files.c b/usr.bin/sort/files.c deleted file mode 100644 index f53d45678f36..000000000000 --- a/usr.bin/sort/files.c +++ /dev/null @@ -1,372 +0,0 @@ -/* $NetBSD: files.c,v 1.16 2001/02/19 20:50:17 jdolecek Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Peter McIlroy. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "sort.h" -#include "fsort.h" - -#ifndef lint -__RCSID("$NetBSD: files.c,v 1.16 2001/02/19 20:50:17 jdolecek Exp $"); -__SCCSID("@(#)files.c 8.1 (Berkeley) 6/6/93"); -#endif /* not lint */ - -#include <string.h> - -static int seq __P((FILE *, DBT *, DBT *)); - -/* - * this is the subroutine for file management for fsort(). - * It keeps the buffers for all temporary files. - */ -int -getnext(binno, infl0, filelist, nfiles, pos, end, dummy) - int binno, infl0; - struct filelist *filelist; - int nfiles; - RECHEADER *pos; - u_char *end; - struct field *dummy; -{ - int i; - u_char *hp; - static size_t nleft = 0; - static int cnt = 0, flag = -1; - static u_char maxb = 0; - static FILE *fp; - - if (nleft == 0) { - if (binno < 0) /* reset files. */ { - for (i = 0; i < nfiles; i++) { - rewind(fstack[infl0 + i].fp); - fstack[infl0 + i].max_o = 0; - } - flag = -1; - nleft = cnt = 0; - return (-1); - } - maxb = fstack[infl0].maxb; - for (; nleft == 0; cnt++) { - if (cnt >= nfiles) { - cnt = 0; - return (EOF); - } - fp = fstack[infl0 + cnt].fp; - fread(&nleft, sizeof(nleft), 1, fp); - if (binno < maxb) - fstack[infl0+cnt].max_o - += sizeof(nleft) + nleft; - else if (binno == maxb) { - if (binno != fstack[infl0].lastb) { - fseek(fp, fstack[infl0+ - cnt].max_o, SEEK_SET); - fread(&nleft, sizeof(nleft), 1, fp); - } - if (nleft == 0) - fclose(fp); - } else if (binno == maxb + 1) { /* skip a bin */ - fseek(fp, nleft, SEEK_CUR); - fread(&nleft, sizeof(nleft), 1, fp); - flag = cnt; - } - } - } - if ((u_char *) pos > end - sizeof(TRECHEADER)) - return (BUFFEND); - fread(pos, sizeof(TRECHEADER), 1, fp); - if (end - pos->data < pos->length) { - hp = ((u_char *)pos) + sizeof(TRECHEADER); - for (i = sizeof(TRECHEADER); i ; i--) - ungetc(*--hp, fp); - return (BUFFEND); - } - fread(pos->data, pos->length, 1, fp); - nleft -= pos->length + sizeof(TRECHEADER); - if (nleft == 0 && binno == fstack[infl0].maxb) - fclose(fp); - return (0); -} - -/* - * this is called when there is no special key. It's only called - * in the first fsort pass. - */ -int -makeline(flno, top, filelist, nfiles, recbuf, bufend, dummy2) - int flno, top; - struct filelist *filelist; - int nfiles; - RECHEADER *recbuf; - u_char *bufend; - struct field *dummy2; -{ - static u_char *obufend; - static size_t osz; - char *pos; - static int filenum = 0, overflow = 0; - static FILE *fp = 0; - int c; - - pos = (char *) recbuf->data; - if (overflow) { - /* - * Buffer shortage is solved by either of two ways: - * o flush previous buffered data and start using the - * buffer from start (see fsort()) - * o realloc buffer and bump bufend - * - * The former is preferred, realloc is only done when - * there is exactly one item in buffer which does not fit. - */ - if (bufend == obufend) - memmove(pos, bufend - osz, osz); - - pos += osz; - overflow = 0; - } - for (;;) { - if (flno >= 0 && (fp = fstack[flno].fp) == NULL) - return (EOF); - else if (fp == NULL) { - if (filenum >= nfiles) - return (EOF); - if (!(fp = fopen(filelist->names[filenum], "r"))) - err(2, "%s", filelist->names[filenum]); - filenum++; - } - while ((pos < (char *)bufend) && ((c = getc(fp)) != EOF)) { - if ((*pos++ = c) == REC_D) { - recbuf->offset = 0; - recbuf->length = pos - (char *) recbuf->data; - return (0); - } - } - if (pos >= (char *)bufend) { - if (recbuf->data < bufend) { - overflow = 1; - obufend = bufend; - osz = (pos - (char *) recbuf->data); - } - return (BUFFEND); - } else if (c == EOF) { - if (recbuf->data != (u_char *) pos) { - *pos++ = REC_D; - recbuf->offset = 0; - recbuf->length = pos - (char *) recbuf->data; - return (0); - } - FCLOSE(fp); - fp = 0; - if (flno >= 0) - fstack[flno].fp = 0; - } else { - - warnx("makeline: line too long: ignoring '%.100s...'", recbuf->data); - - /* Consume the rest of line from input */ - while((c = getc(fp)) != REC_D && c != EOF) - ; - - recbuf->offset = 0; - recbuf->length = 0; - - return (BUFFEND); - } - } -} - -/* - * This generates keys. It's only called in the first fsort pass - */ -int -makekey(flno, top, filelist, nfiles, recbuf, bufend, ftbl) - int flno, top; - struct filelist *filelist; - int nfiles; - RECHEADER *recbuf; - u_char *bufend; - struct field *ftbl; -{ - static int filenum = 0; - static FILE *dbdesc = 0; - static DBT dbkey[1], line[1]; - static int overflow = 0; - int c; - - if (overflow) { - overflow = enterkey(recbuf, line, bufend - (u_char *)recbuf, - ftbl); - if (overflow) - return (BUFFEND); - else - return (0); - } - - for (;;) { - if (flno >= 0) { - if (!(dbdesc = fstack[flno].fp)) - return (EOF); - } else if (!dbdesc) { - if (filenum >= nfiles) - return (EOF); - dbdesc = fopen(filelist->names[filenum], "r"); - if (!dbdesc) - err(2, "%s", filelist->names[filenum]); - filenum++; - } - if (!(c = seq(dbdesc, line, dbkey))) { - if ((signed)line->size > bufend - recbuf->data) { - overflow = 1; - } else { - overflow = enterkey(recbuf, line, - bufend - (u_char *) recbuf, ftbl); - } - if (overflow) - return (BUFFEND); - else - return (0); - } - if (c == EOF) { - FCLOSE(dbdesc); - dbdesc = 0; - if (flno >= 0) - fstack[flno].fp = 0; - } else { - ((char *) line->data)[60] = '\000'; - warnx("makekey: line too long: ignoring %.100s...", - (char *)line->data); - } - } -} - -/* - * get a key/line pair from fp - */ -static int -seq(fp, line, key) - FILE *fp; - DBT *key, *line; -{ - static char *buf, flag = 1; - char *end, *pos; - int c; - - if (flag) { - flag = 0; - buf = (char *) linebuf; - end = buf + linebuf_size; - line->data = buf; - } - pos = buf; - while ((c = getc(fp)) != EOF) { - if ((*pos++ = c) == REC_D) { - line->size = pos - buf; - return (0); - } - if (pos == end) { - linebuf_size *= 2; - linebuf = realloc(linebuf, linebuf_size); - if (!linebuf) - err(2, "realloc of linebuf to %lu bytes failed", - (unsigned long)linebuf_size); - - end = linebuf + linebuf_size; - pos = linebuf + (pos - buf); - line->data = buf = (char *)linebuf; - continue; - } - } - if (pos != buf) { - *pos++ = REC_D; - line->size = pos - buf; - return (0); - } else - return (EOF); -} - -/* - * write a key/line pair to a temporary file - */ -void -putrec(rec, fp) - const RECHEADER *rec; - FILE *fp; -{ - EWRITE(rec, 1, rec->length + sizeof(TRECHEADER), fp); -} - -/* - * write a line to output - */ -void -putline(rec, fp) - const RECHEADER *rec; - FILE *fp; -{ - EWRITE(rec->data+rec->offset, 1, rec->length - rec->offset, fp); -} - -/* - * get a record from a temporary file. (Used by merge sort.) - */ -int -geteasy(flno, top, filelist, nfiles, rec, end, dummy2) - int flno, top; - struct filelist *filelist; - int nfiles; - RECHEADER *rec; - u_char *end; - struct field *dummy2; -{ - int i; - FILE *fp; - - fp = fstack[flno].fp; - if ((u_char *) rec > end - sizeof(TRECHEADER)) - return (BUFFEND); - if (!fread(rec, 1, sizeof(TRECHEADER), fp)) { - fclose(fp); - fstack[flno].fp = 0; - return (EOF); - } - if (end - rec->data < rec->length) { - for (i = sizeof(TRECHEADER) - 1; i >= 0; i--) - ungetc(*((char *) rec + i), fp); - return (BUFFEND); - } - fread(rec->data, rec->length, 1, fp); - return (0); -} diff --git a/usr.bin/sort/fsort.c b/usr.bin/sort/fsort.c deleted file mode 100644 index a38c79da6458..000000000000 --- a/usr.bin/sort/fsort.c +++ /dev/null @@ -1,358 +0,0 @@ -/* $NetBSD: fsort.c,v 1.19 2001/05/15 11:19:45 jdolecek Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Peter McIlroy. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Read in the next bin. If it fits in one segment sort it; - * otherwise refine it by segment deeper by one character, - * and try again on smaller bins. Sort the final bin at this level - * of recursion to keep the head of fstack at 0. - * After PANIC passes, abort to merge sort. - */ -#include "sort.h" -#include "fsort.h" - -#ifndef lint -__RCSID("$NetBSD: fsort.c,v 1.19 2001/05/15 11:19:45 jdolecek Exp $"); -__SCCSID("@(#)fsort.c 8.1 (Berkeley) 6/6/93"); -#endif /* not lint */ - -#include <stdlib.h> -#include <string.h> - -static const u_char **keylist = 0; -u_char *buffer = 0, *linebuf = 0; -size_t bufsize = DEFBUFSIZE; -size_t linebuf_size; -struct tempfile fstack[MAXFCT]; -extern char *toutpath; -#define FSORTMAX 4 -int PANIC = FSORTMAX; - -#define MSTART (MAXFCT - MERGE_FNUM) -#define SALIGN(n) ((n+sizeof(length_t)-1) & ~(sizeof(length_t)-1)) - -void -fsort(binno, depth, top, filelist, nfiles, outfp, ftbl) - int binno, depth, top; - struct filelist *filelist; - int nfiles; - FILE *outfp; - struct field *ftbl; -{ - const u_char **keypos; - u_char *bufend, *tmpbuf; - u_char *weights; - int ntfiles, mfct = 0, total, i, maxb, lastb, panic = 0; - int c, nelem, base; - long sizes [NBINS+1]; - get_func_t get; - struct recheader *crec; - struct field tfield[2]; - FILE *prevfp, *tailfp[FSORTMAX+1]; - - memset(tailfp, 0, sizeof(tailfp)); - prevfp = outfp; - memset(tfield, 0, sizeof(tfield)); - if (ftbl[0].flags & R) - tfield[0].weights = Rascii; - else - tfield[0].weights = ascii; - tfield[0].icol.num = 1; - weights = ftbl[0].weights; - if (!buffer) { - buffer = malloc(bufsize); - keylist = malloc(MAXNUM * sizeof(u_char *)); - memset(keylist, 0, MAXNUM * sizeof(u_char *)); - if (!SINGL_FLD) { - linebuf_size = DEFLLEN; - if ((linebuf = malloc(linebuf_size)) == NULL) - errx(2, "cannot allocate memory"); - } - } - bufend = buffer + bufsize; - if (binno >= 0) { - base = top + nfiles; - get = getnext; - } else { - base = 0; - if (SINGL_FLD) - get = makeline; - else - get = makekey; - } - for (;;) { - memset(sizes, 0, sizeof(sizes)); - c = ntfiles = 0; - if (binno == weights[REC_D] && - !(SINGL_FLD && ftbl[0].flags & F)) { /* pop */ - rd_append(weights[REC_D], top, - nfiles, prevfp, buffer, bufend); - break; - } else if (binno == weights[REC_D]) { - depth = 0; /* start over on flat weights */ - ftbl = tfield; - weights = ftbl[0].weights; - } - while (c != EOF) { - keypos = keylist; - nelem = 0; - crec = (RECHEADER *) buffer; - - do_read: - while((c = get(binno, top, filelist, nfiles, crec, - bufend, ftbl)) == 0) { - *keypos++ = crec->data + depth; - if (++nelem == MAXNUM) { - c = BUFFEND; - break; - } - crec =(RECHEADER *) ((char *) crec + - SALIGN(crec->length) + sizeof(TRECHEADER)); - } - - if (c == BUFFEND && nelem < MAXNUM - && bufsize < MAXBUFSIZE) { - const u_char **keyp; - u_char *oldb = buffer; - - /* buffer was too small for data, allocate - * bigger buffer */ - bufsize *= 2; - buffer = realloc(buffer, bufsize); - if (!buffer) { - err(2, "failed to realloc buffer to %ld bytes", - (unsigned long) bufsize); - } - bufend = buffer + bufsize; - - /* patch up keylist[] */ - for(keyp = &keypos[-1]; keyp >= keylist; keyp--) - *keyp = buffer + (*keyp - oldb); - - crec = (RECHEADER *) (buffer + ((u_char *)crec - oldb)); - goto do_read; - } - - if (c != BUFFEND && !ntfiles && !mfct) { - /* do not push */ - continue; - } - - /* push */ - if (panic >= PANIC) { - fstack[MSTART + mfct].fp = ftmp(); - if ((stable_sort) - ? sradixsort(keylist, nelem, - weights, REC_D) - : radixsort(keylist, nelem, - weights, REC_D) ) - err(2, NULL); - append(keylist, nelem, depth, - fstack[MSTART + mfct].fp, putrec, - ftbl); - mfct++; - /* reduce number of open files */ - if (mfct == MERGE_FNUM ||(c == EOF && ntfiles)) { - /* - * Only copy extra incomplete crec - * data if there are any. - */ - int nodata = (bufend >= (u_char *)crec - && bufend <= crec->data); - - if (!nodata) { - tmpbuf = malloc(bufend - - crec->data); - memmove(tmpbuf, crec->data, - bufend - crec->data); - } - - fstack[base + ntfiles].fp = ftmp(); - fmerge(0, MSTART, filelist, - mfct, geteasy, fstack[base].fp, - putrec, ftbl); - ntfiles++; - mfct = 0; - - if (!nodata) { - memmove(crec->data, tmpbuf, - bufend - crec->data); - free(tmpbuf); - } - } - } else { - fstack[base + ntfiles].fp= ftmp(); - onepass(keylist, depth, nelem, sizes, - weights, fstack[base + ntfiles].fp); - ntfiles++; - } - } - if (!ntfiles && !mfct) { /* everything in memory--pop */ - if (nelem > 1 - && ((stable_sort) - ? sradixsort(keylist, nelem, weights, REC_D) - : radixsort(keylist, nelem, weights, REC_D) )) - err(2, NULL); - if (nelem > 0) - append(keylist, nelem, depth, outfp, putline, ftbl); - break; /* pop */ - } - if (panic >= PANIC) { - if (!ntfiles) - fmerge(0, MSTART, filelist, mfct, geteasy, - outfp, putline, ftbl); - else - fmerge(0, base, filelist, ntfiles, geteasy, - outfp, putline, ftbl); - break; - - } - total = maxb = lastb = 0; /* find if one bin dominates */ - for (i = 0; i < NBINS; i++) - if (sizes[i]) { - if (sizes[i] > sizes[maxb]) - maxb = i; - lastb = i; - total += sizes[i]; - } - if (sizes[maxb] < max((total / 2) , BUFSIZE)) - maxb = lastb; /* otherwise pop after last bin */ - fstack[base].lastb = lastb; - fstack[base].maxb = maxb; - - /* start refining next level. */ - getnext(-1, base, NULL, ntfiles, crec, bufend, 0); /* rewind */ - for (i = 0; i < maxb; i++) { - if (!sizes[i]) /* bin empty; step ahead file offset */ - getnext(i, base, NULL,ntfiles, crec, bufend, 0); - else - fsort(i, depth+1, base, filelist, ntfiles, - outfp, ftbl); - } - - get = getnext; - - if (lastb != maxb) { - if (prevfp != outfp) - tailfp[panic] = prevfp; - prevfp = ftmp(); - for (i = maxb+1; i <= lastb; i++) - if (!sizes[i]) - getnext(i, base, NULL, ntfiles, crec, - bufend,0); - else - fsort(i, depth+1, base, filelist, - ntfiles, prevfp, ftbl); - } - - /* sort biggest (or last) bin at this level */ - depth++; - panic++; - binno = maxb; - top = base; - nfiles = ntfiles; /* so overwrite them */ - } - if (prevfp != outfp) { - concat(outfp, prevfp); - fclose(prevfp); - } - for (i = panic; i >= 0; --i) - if (tailfp[i]) { - concat(outfp, tailfp[i]); - fclose(tailfp[i]); - } - - /* If on top level, free our structures */ - if (depth == 0) { - free(keylist), keylist = NULL; - free(buffer), buffer = NULL; - } -} - -/* - * This is one pass of radix exchange, dumping the bins to disk. - */ -#define swap(a, b, t) t = a, a = b, b = t -void -onepass(a, depth, n, sizes, tr, fp) - const u_char **a; - int depth; - long n, sizes[]; - u_char *tr; - FILE *fp; -{ - size_t tsizes[NBINS+1]; - const u_char **bin[257], ***bp, ***bpmax, **top[256], ***tp; - static int histo[256]; - int *hp; - int c; - const u_char **an, *t, **aj; - const u_char **ak, *r; - - memset(tsizes, 0, sizeof(tsizes)); - depth += sizeof(TRECHEADER); - an = &a[n]; - for (ak = a; ak < an; ak++) { - histo[c = tr[**ak]]++; - tsizes[c] += ((const RECHEADER *) (*ak -= depth))->length; - } - - bin[0] = a; - bpmax = bin + 256; - tp = top, hp = histo; - for (bp = bin; bp < bpmax; bp++) { - *tp++ = *(bp+1) = *bp + (c = *hp); - *hp++ = 0; - if (c <= 1) - continue; - } - for (aj = a; aj < an; *aj = r, aj = bin[c+1]) - for (r = *aj; aj < (ak = --top[c = tr[r[depth]]]) ;) - swap(*ak, r, t); - - for (ak = a, c = 0; c < 256; c++) { - an = bin[c+1]; - n = an - ak; - tsizes[c] += n * sizeof(TRECHEADER); - /* tell getnext how many elements in this bin, this segment. */ - EWRITE(&tsizes[c], sizeof(size_t), 1, fp); - sizes[c] += tsizes[c]; - for (; ak < an; ++ak) - putrec((const RECHEADER *) *ak, fp); - } -} diff --git a/usr.bin/sort/fsort.h b/usr.bin/sort/fsort.h deleted file mode 100644 index f1d170202715..000000000000 --- a/usr.bin/sort/fsort.h +++ /dev/null @@ -1,77 +0,0 @@ -/* $NetBSD: fsort.h,v 1.8 2001/02/19 20:50:17 jdolecek Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Peter McIlroy. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)fsort.h 8.1 (Berkeley) 6/6/93 - */ - -#define BUFSIZE (1<<20) -#define MAXNUM 131072 /* low guess at average record count */ -#define BUFFEND (EOF-2) -#define MAXFCT 1000 -#define DEFLLEN 65536 - -/* - * Default (initial) and maximum size of record buffer for fsort(). - * Note that no more than MAXNUM records are stored in the buffer, - * even if the buffer is not full yet. - */ -#define DEFBUFSIZE (1 << 20) /* 1MB */ -#define MAXBUFSIZE (8 << 20) /* 10 MB */ - -/* - * Number of files merge() can merge in one pass. - * This should be power of two so that it's possible to use this value - * for rouding. - */ -#define MERGE_FNUM 16 - -extern u_char *buffer, *linebuf; -extern size_t bufsize, linebuf_size; - -/* temp files in the stack have a file descriptor, a largest bin (maxb) - * which becomes the last non-empty bin (lastb) when the actual largest - * bin is smaller than max(half the total file, BUFSIZE) - * Max_o is the offset of maxb so it can be sought after the other bins - * are sorted. -*/ -struct tempfile { - FILE *fp; - u_char maxb; - u_char lastb; - int max_o; -}; -extern struct tempfile fstack[MAXFCT]; diff --git a/usr.bin/sort/init.c b/usr.bin/sort/init.c deleted file mode 100644 index 8b965b196a7c..000000000000 --- a/usr.bin/sort/init.c +++ /dev/null @@ -1,355 +0,0 @@ -/* $NetBSD: init.c,v 1.5 2001/02/19 20:50:17 jdolecek Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Peter McIlroy. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "sort.h" - -#ifndef lint -__RCSID("$NetBSD: init.c,v 1.5 2001/02/19 20:50:17 jdolecek Exp $"); -__SCCSID("@(#)init.c 8.1 (Berkeley) 6/6/93"); -#endif /* not lint */ - -#include <ctype.h> -#include <string.h> - -static void insertcol __P((struct field *)); -static const char *setcolumn __P((const char *, struct field *, int)); -int setfield __P((const char *, struct field *, int)); - -extern struct coldesc clist[(ND+1)*2]; -extern int ncols; -u_char gweights[NBINS]; - -/* - * masks of ignored characters. Alltable is 256 ones. - */ -static u_char alltable[NBINS], dtable[NBINS], itable[NBINS]; - -/* - * clist (list of columns which correspond to one or more icol or tcol) - * is in increasing order of columns. - * Fields are kept in increasing order of fields. - */ - -/* - * keep clist in order--inserts a column in a sorted array - */ -static void -insertcol(field) - struct field *field; -{ - int i; - for (i = 0; i < ncols; i++) - if (field->icol.num <= clist[i].num) - break; - if (field->icol.num != clist[i].num) { - memmove(clist+i+1, clist+i, sizeof(COLDESC)*(ncols-i)); - clist[i].num = field->icol.num; - ncols++; - } - if (field->tcol.num && field->tcol.num != field->icol.num) { - for (i = 0; i < ncols; i++) - if (field->tcol.num <= clist[i].num) - break; - if (field->tcol.num != clist[i].num) { - memmove(clist+i+1, clist+i,sizeof(COLDESC)*(ncols-i)); - clist[i].num = field->tcol.num; - ncols++; - } - } -} - -/* - * matches fields with the appropriate columns--n^2 but who cares? - */ -void -fldreset(fldtab) - struct field *fldtab; -{ - int i; - fldtab[0].tcol.p = clist+ncols-1; - for (++fldtab; fldtab->icol.num; ++fldtab) { - for (i = 0; fldtab->icol.num != clist[i].num; i++) - ; - fldtab->icol.p = clist + i; - if (!fldtab->tcol.num) - continue; - for (i = 0; fldtab->tcol.num != clist[i].num; i++) - ; - fldtab->tcol.p = clist + i; - } -} - -/* - * interprets a column in a -k field - */ -static const char * -setcolumn(pos, cur_fld, gflag) - const char *pos; - struct field *cur_fld; - int gflag; -{ - struct column *col; - int tmp; - col = cur_fld->icol.num ? (&(*cur_fld).tcol) : (&(*cur_fld).icol); - pos += sscanf(pos, "%d", &(col->num)); - while (isdigit(*pos)) - pos++; - if (col->num <= 0 && !(col->num == 0 && col == &(cur_fld->tcol))) - errx(2, "field numbers must be positive"); - if (*pos == '.') { - if (!col->num) - errx(2, "cannot indent end of line"); - ++pos; - pos += sscanf(pos, "%d", &(col->indent)); - while (isdigit(*pos)) - pos++; - if (&cur_fld->icol == col) - col->indent--; - if (col->indent < 0) - errx(2, "illegal offset"); - } - if (optval(*pos, cur_fld->tcol.num)) - while ((tmp = optval(*pos, cur_fld->tcol.num))) { - cur_fld->flags |= tmp; - pos++; - } - if (cur_fld->icol.num == 0) - cur_fld->icol.num = 1; - return (pos); -} - -int -setfield(pos, cur_fld, gflag) - const char *pos; - struct field *cur_fld; - int gflag; -{ - static int nfields = 0; - int tmp; - - if (++nfields == ND) - errx(2, "too many sort keys. (Limit is %d)", ND-1); - - cur_fld->weights = ascii; - cur_fld->mask = alltable; - - pos = setcolumn(pos, cur_fld, gflag); - if (*pos == '\0') /* key extends to EOL. */ - cur_fld->tcol.num = 0; - else { - if (*pos != ',') - errx(2, "illegal field descriptor"); - setcolumn((++pos), cur_fld, gflag); - } - if (!cur_fld->flags) - cur_fld->flags = gflag; - tmp = cur_fld->flags; - - /* - * Assign appropriate mask table and weight table. - * If the global weights are reversed, the local field - * must be "re-reversed". - */ - if (((tmp & R) ^ (gflag & R)) && (tmp & F)) - cur_fld->weights = RFtable; - else if (tmp & F) - cur_fld->weights = Ftable; - else if ((tmp & R) ^ (gflag & R)) - cur_fld->weights = Rascii; - - if (tmp & I) - cur_fld->mask = itable; - else if (tmp & D) - cur_fld->mask = dtable; - - cur_fld->flags |= (gflag & (BI | BT)); - if (!cur_fld->tcol.indent) /* BT has no meaning at end of field */ - cur_fld->flags &= ~BT; - - if (cur_fld->tcol.num && !(!(cur_fld->flags & BI) - && cur_fld->flags & BT) && (cur_fld->tcol.num <= cur_fld->icol.num - && cur_fld->tcol.indent < cur_fld->icol.indent)) - errx(2, "fields out of order"); - insertcol(cur_fld); - return (cur_fld->tcol.num); -} - -int -optval(desc, tcolflag) - int desc, tcolflag; -{ - switch(desc) { - case 'b': - if (!tcolflag) - return (BI); - else - return (BT); - case 'd': return (D); - case 'f': return (F); - case 'i': return (I); - case 'n': return (N); - case 'r': return (R); - default: return (0); - } -} - -void -fixit(argc, argv) - int *argc; - char **argv; -{ - int i, j, v, w, x; - static char vbuf[ND*20], *vpos, *tpos; - vpos = vbuf; - - for (i = 1; i < *argc; i++) { - if (argv[i][0] == '+') { - tpos = argv[i]+1; - argv[i] = vpos; - vpos += sprintf(vpos, "-k"); - tpos += sscanf(tpos, "%d", &v); - while (isdigit(*tpos)) - tpos++; - vpos += sprintf(vpos, "%d", v+1); - if (*tpos == '.') { - ++tpos; - tpos += sscanf(tpos, "%d", &x); - vpos += sprintf(vpos, ".%d", x+1); - } - while (*tpos) - *vpos++ = *tpos++; - vpos += sprintf(vpos, ","); - if (argv[i+1] && - argv[i+1][0] == '-' && isdigit(argv[i+1][1])) { - tpos = argv[i+1] + 1; - tpos += sscanf(tpos, "%d", &w); - while (isdigit(*tpos)) - tpos++; - x = 0; - if (*tpos == '.') { - ++tpos; - tpos += sscanf(tpos, "%d", &x); - while (isdigit(*tpos)) - tpos++; - } - if (x) { - vpos += sprintf(vpos, "%d", w+1); - vpos += sprintf(vpos, ".%d", x); - } else - vpos += sprintf(vpos, "%d", w); - while (*tpos) - *vpos++ = *tpos++; - for (j= i+1; j < *argc; j++) - argv[j] = argv[j+1]; - *argc -= 1; - } - } - } -} - -/* - * ascii, Rascii, Ftable, and RFtable map - * REC_D -> REC_D; {not REC_D} -> {not REC_D}. - * gweights maps REC_D -> (0 or 255); {not REC_D} -> {not gweights[REC_D]}. - * Note: when sorting in forward order, to encode character zero in a key, - * use \001\001; character 1 becomes \001\002. In this case, character 0 - * is reserved for the field delimiter. Analagously for -r (fld_d = 255). - * Note: this is only good for ASCII sorting. For different LC 's, - * all bets are off. See also num_init in number.c - */ -void -settables(gflags) - int gflags; -{ - u_char *wts; - int i, incr; - for (i=0; i < 256; i++) { - ascii[i] = i; - if (i > REC_D && i < 255 - REC_D+1) - Rascii[i] = 255 - i + 1; - else - Rascii[i] = 255 - i; - if (islower(i)) { - Ftable[i] = Ftable[toupper(i)]; - RFtable[i] = RFtable[toupper(i)]; - } else if (REC_D>= 'A' && REC_D < 'Z' && i < 'a' && i > REC_D) { - Ftable[i] = i + 1; - RFtable[i] = Rascii[i] - 1; - } else { - Ftable[i] = i; - RFtable[i] = Rascii[i]; - } - alltable[i] = 1; - - if (i == '\n' || isprint(i)) - itable[i] = 1; - else - itable[i] = 0; - - if (i == '\n' || i == '\t' || i == ' ' || isalnum(i)) - dtable[i] = 1; - else - dtable[i] = 0; - } - - Rascii[REC_D] = RFtable[REC_D] = REC_D; - if (isupper(REC_D)) - Ftable[tolower(REC_D)]++; - - if ((gflags & R) && !((gflags & F) && SINGL_FLD)) - wts = Rascii; - else if (!((gflags & F) && SINGL_FLD)) - wts = ascii; - else if (gflags & R) - wts = RFtable; - else - wts = Ftable; - - memmove(gweights, wts, sizeof(gweights)); - incr = (gflags & R) ? -1 : 1; - for (i = 0; i < REC_D; i++) - gweights[i] += incr; - gweights[REC_D] = ((gflags & R) ? 255 : 0); - if (SINGL_FLD && (gflags & F)) { - for (i = 0; i < REC_D; i++) { - ascii[i] += incr; - Rascii[i] += incr; - } - ascii[REC_D] = Rascii[REC_D] = gweights[REC_D]; - } -} diff --git a/usr.bin/sort/msort.c b/usr.bin/sort/msort.c deleted file mode 100644 index f66db0b2e02d..000000000000 --- a/usr.bin/sort/msort.c +++ /dev/null @@ -1,390 +0,0 @@ -/* $NetBSD: msort.c,v 1.9 2001/01/19 10:50:31 jdolecek Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Peter McIlroy. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "sort.h" -#include "fsort.h" - -#ifndef lint -__RCSID("$NetBSD: msort.c,v 1.9 2001/01/19 10:50:31 jdolecek Exp $"); -__SCCSID("@(#)msort.c 8.1 (Berkeley) 6/6/93"); -#endif /* not lint */ - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -/* Subroutines using comparisons: merge sort and check order */ -#define DELETE (1) - -typedef struct mfile { - u_char *end; - short flno; - struct recheader rec[1]; -} MFILE; - -static u_char *wts, *wts1 = NULL; - -static int cmp __P((RECHEADER *, RECHEADER *)); -static int insert __P((struct mfile **, struct mfile **, int, int)); - -void -fmerge(binno, top, filelist, nfiles, get, outfp, fput, ftbl) - int binno, top; - struct filelist *filelist; - int nfiles; - get_func_t get; - FILE *outfp; - put_func_t fput; - struct field *ftbl; -{ - FILE *tout; - int i, j, last; - put_func_t put; - struct tempfile *l_fstack; - - wts = ftbl->weights; - if (!UNIQUE && SINGL_FLD && ftbl->flags & F) - wts1 = (ftbl->flags & R) ? Rascii : ascii; - - if (!buffer) { - buffer = malloc(bufsize); - if (!buffer) - err(2, "fmerge(): realloc"); - - if (!linebuf && !SINGL_FLD) { - linebuf_size = DEFLLEN; - linebuf = malloc(linebuf_size); - } - } - - if (binno >= 0) - l_fstack = fstack + top; - else - l_fstack = fstack; - - while (nfiles) { - put = putrec; - for (j = 0; j < nfiles; j += MERGE_FNUM) { - if (nfiles <= MERGE_FNUM) { - tout = outfp; - put = fput; - } - else - tout = ftmp(); - last = min(MERGE_FNUM, nfiles - j); - if (binno < 0) { - for (i = 0; i < last; i++) - if (!(l_fstack[i+MAXFCT-1-MERGE_FNUM].fp = - fopen(filelist->names[j+i], "r"))) - err(2, "%s", - filelist->names[j+i]); - merge(MAXFCT-1-MERGE_FNUM, last, get, tout, put, ftbl); - } else { - for (i = 0; i< last; i++) - rewind(l_fstack[i+j].fp); - merge(top+j, last, get, tout, put, ftbl); - } - if (nfiles > MERGE_FNUM) - l_fstack[j/MERGE_FNUM].fp = tout; - } - nfiles = (nfiles + (MERGE_FNUM - 1)) / MERGE_FNUM; - if (nfiles == 1) - nfiles = 0; - if (binno < 0) { - binno = 0; - get = geteasy; - top = 0; - } - } -} - -void -merge(infl0, nfiles, get, outfp, put, ftbl) - int infl0, nfiles; - get_func_t get; - put_func_t put; - FILE *outfp; - struct field *ftbl; -{ - int c, i, j, nf = nfiles; - struct mfile *flist[MERGE_FNUM], *cfile; - size_t availsz = bufsize; - static void *bufs[MERGE_FNUM+1]; - static size_t bufs_sz[MERGE_FNUM+1]; - - /* - * We need nfiles + 1 buffers. One is 'buffer', the - * rest needs to be allocated. - */ - bufs[0] = buffer; - bufs_sz[0] = bufsize; - for(i=1; i < nfiles+1; i++) { - if (bufs[i]) - continue; - - bufs[i] = malloc(DEFLLEN); - if (!bufs[i]) - err(2, "merge(): realloc"); - bufs_sz[i] = DEFLLEN; - } - - for (i = j = 0; i < nfiles; i++) { - cfile = (struct mfile *) bufs[j]; - cfile->flno = infl0 + j; - cfile->end = (u_char *) bufs[j] + bufs_sz[j]; - for (c = 1; c == 1;) { - if (EOF == (c = get(cfile->flno, 0, NULL, nfiles, - cfile->rec, cfile->end, ftbl))) { - --i; - --nfiles; - break; - } - - if (c == BUFFEND) { - cfile = realloc(bufs[j], bufs_sz[j] *= 2); - bufs[j] = (void *) cfile; - - if (!cfile) - err(2, "merge(): realloc"); - - cfile->end = (u_char *)cfile + bufs_sz[j]; - - c = 1; - continue; - } - - if (i) - c = insert(flist, &cfile, i, !DELETE); - else - flist[0] = cfile; - } - j++; - } - - cfile = (struct mfile *) bufs[nf]; - cfile->flno = flist[0]->flno; - cfile->end = (u_char *) cfile + bufs_sz[nf]; - while (nfiles) { - for (c = 1; c == 1;) { - if (EOF == (c = get(cfile->flno, 0, NULL, nfiles, - cfile->rec, cfile->end, ftbl))) { - put(flist[0]->rec, outfp); - memmove(flist, flist + 1, - sizeof(MFILE *) * (--nfiles)); - cfile->flno = flist[0]->flno; - break; - } - if (c == BUFFEND) { - char *oldbuf = (char *) cfile; - availsz = (char *) cfile->end - oldbuf; - availsz *= 2; - cfile = realloc(oldbuf, availsz); - for(i=0; i < nf+1; i++) { - if (bufs[i] == oldbuf) { - bufs[i] = (char *)cfile; - bufs_sz[i] = availsz; - break; - } - } - - if (!cfile) - err(2, "merge: realloc"); - - cfile->end = (u_char *)cfile + availsz; - c = 1; - continue; - } - - if (!(c = insert(flist, &cfile, nfiles, DELETE))) - put(cfile->rec, outfp); - } - } - - if (bufs_sz[0] > bufsize) { - buffer = bufs[0]; - bufsize = bufs_sz[0]; - } -} - -/* - * if delete: inserts *rec in flist, deletes flist[0], and leaves it in *rec; - * otherwise just inserts *rec in flist. - */ -static int -insert(flist, rec, ttop, delete) - struct mfile **flist, **rec; - int delete, ttop; /* delete = 0 or 1 */ -{ - struct mfile *tmprec = *rec; - int mid, top = ttop, bot = 0, cmpv = 1; - - for (mid = top/2; bot +1 != top; mid = (bot+top)/2) { - cmpv = cmp(tmprec->rec, flist[mid]->rec); - if (cmpv < 0) - top = mid; - else if (cmpv > 0) - bot = mid; - else { - if (UNIQUE) - break; - - if (stable_sort) { - /* - * Apply sort by fileno, to give priority - * to earlier specified files, hence providing - * more stable sort. - * If fileno is same, the new record should - * be put _after_ the previous entry. - */ - cmpv = tmprec->flno - flist[mid]->flno; - if (cmpv >= 0) - bot = mid; - else /* cmpv == 0 */ - bot = mid - 1; - } else { - /* non-stable sort */ - bot = mid - 1; - } - - break; - } - } - - if (delete) { - if (UNIQUE) { - if (!bot && cmpv) - cmpv = cmp(tmprec->rec, flist[0]->rec); - if (!cmpv) - return (1); - } - tmprec = flist[0]; - if (bot) - memmove(flist, flist+1, bot * sizeof(MFILE **)); - flist[bot] = *rec; - *rec = tmprec; - (*rec)->flno = flist[0]->flno; - return (0); - } else { - if (!bot && !(UNIQUE && !cmpv)) { - cmpv = cmp(tmprec->rec, flist[0]->rec); - if (cmpv < 0) - bot = -1; - } - if (UNIQUE && !cmpv) - return (1); - bot++; - memmove(flist + bot+1, flist + bot, - (ttop - bot) * sizeof(MFILE **)); - flist[bot] = *rec; - return (0); - } -} - -/* - * check order on one file - */ -void -order(filelist, get, ftbl) - struct filelist *filelist; - get_func_t get; - struct field *ftbl; -{ - u_char *crec_end, *prec_end, *trec_end; - int c; - RECHEADER *crec, *prec, *trec; - - if (!SINGL_FLD) - linebuf = malloc(DEFLLEN); - buffer = malloc(2 * (DEFLLEN + sizeof(TRECHEADER))); - crec = (RECHEADER *) buffer; - crec_end = buffer + DEFLLEN + sizeof(TRECHEADER); - prec = (RECHEADER *) (buffer + DEFLLEN + sizeof(TRECHEADER)); - prec_end = buffer + 2*(DEFLLEN + sizeof(TRECHEADER)); - wts = ftbl->weights; - if (SINGL_FLD && (ftbl->flags & F)) - wts1 = (ftbl->flags & R) ? Rascii : ascii; - else - wts1 = NULL; - if (0 == get(-1, 0, filelist, 1, prec, prec_end, ftbl)) - while (0 == get(-1, 0, filelist, 1, crec, crec_end, ftbl)) { - if (0 < (c = cmp(prec, crec))) { - crec->data[crec->length-1] = 0; - errx(1, "found disorder: %s", crec->data+crec->offset); - } - if (UNIQUE && !c) { - crec->data[crec->length-1] = 0; - errx(1, "found non-uniqueness: %s", - crec->data+crec->offset); - } - /* - * Swap pointers so that this record is on place pointed - * to by prec and new record is read to place pointed to by - * crec. - */ - trec = prec; - prec = crec; - crec = trec; - trec_end = prec_end; - prec_end = crec_end; - crec_end = trec_end; - } - exit(0); -} - -static int -cmp(rec1, rec2) - RECHEADER *rec1, *rec2; -{ - int r; - u_char *pos1, *pos2, *end; - u_char *cwts; - for (cwts = wts; cwts; cwts = (cwts == wts1 ? NULL : wts1)) { - pos1 = rec1->data; - pos2 = rec2->data; - if (!SINGL_FLD && (UNIQUE || stable_sort)) - end = pos1 + min(rec1->offset, rec2->offset); - else - end = pos1 + min(rec1->length, rec2->length); - - for (; pos1 < end; ) { - if ((r = cwts[*pos1++] - cwts[*pos2++])) - return (r); - } - } - return (0); -} diff --git a/usr.bin/sort/pathnames.h b/usr.bin/sort/pathnames.h deleted file mode 100644 index dcd404c3f786..000000000000 --- a/usr.bin/sort/pathnames.h +++ /dev/null @@ -1,41 +0,0 @@ -/* $NetBSD: pathnames.h,v 1.2 2000/10/07 18:37:10 bjh21 Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Peter McIlroy. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)pathnames.h 8.1 (Berkeley) 6/6/93 - */ - -#define _PATH_STDIN "/dev/stdin" diff --git a/usr.bin/sort/sort.1 b/usr.bin/sort/sort.1 deleted file mode 100644 index 65c6103168e8..000000000000 --- a/usr.bin/sort/sort.1 +++ /dev/null @@ -1,441 +0,0 @@ -.\" $NetBSD: sort.1,v 1.17 2001/12/08 19:16:07 wiz 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 -.\" the Institute of Electrical and Electronics Engineers, Inc. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)sort.1 8.1 (Berkeley) 6/6/93 -.\" -.Dd January 13, 2001 -.Dt SORT 1 -.Os -.Sh NAME -.Nm sort -.Nd sort or merge text files -.Sh SYNOPSIS -.Nm sort -.Op Fl cmubdfHinrsS -.Op Fl t Ar char -.Op Fl R Ar char -.Oo -.Fl k -.Ar field1 Ns Op Li \&, Ns Ar field2 -.Oc -.Op Fl T Ar dir -.Op Fl o Ar output -.Op Ar -.Sh DESCRIPTION -The -.Nm -utility sorts text files by lines. -Comparisons are based on one or more sort keys extracted -from each line of input, and are performed lexicographically. -By default, if keys are not given, -.Nm -regards each input line as a single field. -.Pp -The following options are available: -.Bl -tag -width Fl -.It Fl c -Check that the single input file is sorted. -If the file is not sorted, -.Nm -produces the appropriate error messages and exits with code 1; otherwise, -.Nm -returns 0. -.Nm -.Fl c -produces no output. -.It Fl m -Merge only; the input files are assumed to be pre-sorted. -.It Fl o Ar output -The argument given is the name of an -.Ar output -file to be used instead of the standard output. -This file can be the same as one of the input files. -.It Fl T Ar dir -Use -.Ar dir -as the directory for temporary files. -The default is the value specified in the environment variable -.Ev TMPDIR or -.Pa /tmp -if -.Ev TMPDIR -is not defined. -.It Fl u -Unique: suppress all but one in each set of lines having equal keys. -If used with the -.Fl c -option, check that there are no lines with duplicate keys. -.El -.Pp -The following options override the default ordering rules. -When ordering options appear independent of key field -specifications, the requested field ordering rules are -applied globally to all sort keys. -When attached to a specific key (see -.Fl k ) , -the ordering options override -all global ordering options for that key. -.Bl -tag -width Fl -.It Fl d -Only blank space and alphanumeric characters -.\" according -.\" to the current setting of LC_CTYPE -are used -in making comparisons. -.It Fl f -Considers all lowercase characters that have uppercase -equivalents to be the same for purposes of comparison. -.It Fl i -Ignore all non-printable characters. -.It Fl n -An initial numeric string, consisting of optional blank space, optional -minus sign, and zero or more digits (including decimal point) -.\" with -.\" optional radix character and thousands -.\" separator -.\" (as defined in the current locale), -is sorted by arithmetic value. -(The -.Fl n -option no longer implies the -.Fl b -option.) -.It Fl r -Reverse the sense of comparisons. -.It Fl S -Don't use stable sort. -Default is to use stable sort. -.It Fl s -Use stable sort. -This is the default. -Provided for compatiblity with other -.Nm -implementations only. -.It Fl H -Use a merge sort instead of a radix sort. -This option should be used for files larger than 60Mb. -.El -.Pp -The treatment of field separators can be altered using these options: -.Bl -tag -width Fl -.It Fl b -Ignores leading blank space when determining the start -and end of a restricted sort key. -A -.Fl b -option specified before the first -.Fl k -option applies globally to all -.Fl k -options. -Otherwise, the -.Fl b -option can be attached independently to each -.Ar field -argument of the -.Fl k -option (see below). -Note that the -.Fl b -option has no effect unless key fields are specified. -.It Fl t Ar char -.Ar char -is used as the field separator character. -The initial -.Ar char -is not considered to be part of a field when determining -key offsets (see below). -Each occurrence of -.Ar char -is significant (for example, -.Dq Ar charchar -delimits an empty field). -If -.Fl t -is not specified, the default field separator is a sequence of -blank-space characters, and consecutive blank spaces do -.Em not -delimit an empty field; further, the initial blank space -.Em is -considered part of a field when determining key offsets. -.It Fl R Ar char -.Ar char -is used as the record separator character. -This should be used with discretion; -.Fl R Ar \*[Lt]alphanumeric\*[Gt] -usually produces undesirable results. -The default record separator is newline. -.It Xo -.Fl k -.Ar field1 Ns Op Li \&, Ns Ar field2 -.Xc -Designates the starting position, -.Ar field1 , -and optional ending position, -.Ar field2 , -of a key field. -The -.Fl k -option replaces the obsolescent options -.Cm \(pl Ns Ar pos1 -and -.Fl Ns Ar pos2 . -.El -.Pp -The following operands are available: -.Bl -tag -width Ar -.It Ar file -The pathname of a file to be sorted, merged, or checked. -If no -.Ar file -operands are specified, or if -a -.Ar file -operand is -.Fl , -the standard input is used. -.El -.Pp -A field is defined as a minimal sequence of characters followed by a -field separator or a newline character. -By default, the first -blank space of a sequence of blank spaces acts as the field separator. -All blank spaces in a sequence of blank spaces are considered -as part of the next field; for example, all blank spaces at -the beginning of a line are considered to be part of the -first field. -.Pp -Fields are specified -by the -.Fl k -.Ar field1 Ns Op \&, Ns Ar field2 -argument. -A missing -.Ar field2 -argument defaults to the end of a line. -.Pp -The arguments -.Ar field1 -and -.Ar field2 -have the form -.Ar m Ns Li \&. Ns Ar n -and can be followed by one or more of the letters -.Cm b , d , f , i , -.Cm n , -and -.Cm r , -which correspond to the options discussed above. -A -.Ar field1 -position specified by -.Ar m Ns Li \&. Ns Ar n -.Pq Ar m , n No \*[Gt] 0 -is interpreted as the -.Ar n Ns th -character in the -.Ar m Ns th -field. -A missing -.Li \&. Ns Ar n -in -.Ar field1 -means -.Ql \&.1 , -indicating the first character of the -.Ar m Ns th -field; if the -.Fl b -option is in effect, -.Ar n -is counted from the first non-blank character in the -.Ar m Ns th -field; -.Ar m Ns Li \&.1b -refers to the first non-blank character in the -.Ar m Ns th -field. -.Pp -A -.Ar field2 -position specified by -.Ar m Ns Li \&. Ns Ar n -is interpreted as -the -.Ar n Ns th -character (including separators) of the -.Ar m Ns th -field. -A missing -.Li \&. Ns Ar n -indicates the last character of the -.Ar m Ns th -field; -.Ar m -= \&0 -designates the end of a line. -Thus the option -.Fl k -.Sm off -.Xo -.Ar v Li \&. Ar x Li \&, -.Ar w Li \&. Ar y -.Xc -.Sm on -is synonymous with the obsolescent option -.Sm off -.Cm \(pl Ar v-\&1 Li \&. Ar x-\&1 -.Fl Ar w-\&1 Li \&. Ar y ; -.Sm on -when -.Ar y -is omitted, -.Fl k -.Sm off -.Ar v Li \&. Ar x Li \&, Ar w -.Sm on -is synonymous with -.Sm off -.Cm \(pl Ar v-\&1 Li \&. Ar x-\&1 -.Fl Ar w+1 Li \&.0 . -.Sm on -The obsolescent -.Cm \(pl Ns Ar pos1 -.Fl Ns Ar pos2 -option is still supported, except for -.Fl Ns Ar w Ns Li \&.0b , -which has no -.Fl k -equivalent. -.Sh RETURN VALUES -Sort exits with one of the following values: -.Bl -tag -width flag -compact -.It 0 -Normal behavior. -.It 1 -On disorder (or non-uniqueness) with the -.Fl c -option -.It 2 -An error occurred. -.El -.Sh ENVIRONMENT -If the following environment variable exists, it is utilized by -.Nm "" . -.Bl -tag -width Ev -.It Ev TMPDIR -.Nm -uses the contents of the -.Ev TMPDIR -environment variable as the path in which to store -temporary files. -.El -.Sh FILES -.Bl -tag -width outputNUMBER+some -compact -.It Pa /tmp/sort.* -Default temporary files. -.It Pa Ar output Ns NUMBER -Temporary file which is used for output if -.Ar output -already exists. -Once sorting is finished, this file replaces -.Ar output -(via -.Xr link 2 -and -.Xr unlink 2 ) . -.El -.Sh SEE ALSO -.Xr comm 1 , -.Xr join 1 , -.Xr uniq 1 , -.Xr qsort 3 , -.Xr radixsort 3 -.Sh HISTORY -A -.Nm -command appeared in -.At v5 . -This -.Nm -implementation appeared in -.Bx 4.4 -and is used since -.Nx 1.6 . -.Sh BUGS -To sort files larger than 60Mb, use -.Nm -.Fl H ; -files larger than 704Mb must be sorted in smaller pieces, then merged. -.Sh NOTES -This -.Nm -has no limits on input line length (other than imposed by available -memory) or any restrictions on bytes allowed within lines. -.Pp -To protect data -.Nm -.Fl o -calls -.Xr link 2 -and -.Xr unlink 2 , -and thus fails on protected directories. -.Pp -Input files should be text files. -If file doesn't end with record separator (which is typically newline), the -.Nm -utility silently supplies one. -.Pp -The current -.Nm -uses lexicographic radix sorting, which requires -that sort keys be kept in memory (as opposed to previous versions which used quick -and merge sorts and did not.) -Thus performance depends highly on efficient choice of sort keys, and the -.Fl b -option and the -.Ar field2 -argument of the -.Fl k -option should be used whenever possible. -Similarly, -.Nm -.Fl k1f -is equivalent to -.Nm -.Fl f -and may take twice as long. diff --git a/usr.bin/sort/sort.c b/usr.bin/sort/sort.c deleted file mode 100644 index 57e235762082..000000000000 --- a/usr.bin/sort/sort.c +++ /dev/null @@ -1,332 +0,0 @@ -/* $NetBSD: sort.c,v 1.26 2001/04/30 00:25:09 ross Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Peter McIlroy. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* Sort sorts a file using an optional user-defined key. - * Sort uses radix sort for internal sorting, and allows - * a choice of merge sort and radix sort for external sorting. - */ - -#include "sort.h" -#include "fsort.h" -#include "pathnames.h" - -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1993\n\ - The Regents of the University of California. All rights reserved.\n"); -#endif /* not lint */ - -#ifndef lint -__RCSID("$NetBSD: sort.c,v 1.26 2001/04/30 00:25:09 ross Exp $"); -__SCCSID("@(#)sort.c 8.1 (Berkeley) 6/6/93"); -#endif /* not lint */ - -#include <sys/types.h> -#include <sys/time.h> -#include <sys/resource.h> - -#include <paths.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <locale.h> - -int REC_D = '\n'; -u_char d_mask[NBINS]; /* flags for rec_d, field_d, <blank> */ -/* - * weight tables. Gweights is one of ascii, Rascii.. - * modified to weight rec_d = 0 (or 255) - */ -u_char ascii[NBINS], Rascii[NBINS], RFtable[NBINS], Ftable[NBINS]; -int SINGL_FLD = 0, SEP_FLAG = 0, UNIQUE = 0; -struct coldesc clist[(ND+1)*2]; -int ncols = 0; -extern struct coldesc clist[(ND+1)*2]; -extern int ncols; - -/* - * Default to stable sort. - */ -int stable_sort = 1; - -char toutpath[MAXPATHLEN]; - -const char *tmpdir; /* where temporary files should be put */ - -static void cleanup __P((void)); -static void onsignal __P((int)); -static void usage __P((const char *)); -static void many_files __P((void)); - -int main __P((int argc, char **argv)); - -int -main(argc, argv) - int argc; - char *argv[]; -{ - get_func_t get; - int ch, i, stdinflag = 0, tmp = 0; - char cflag = 0, mflag = 0; - char *outfile, *outpath = 0; - struct field fldtab[ND+2], *ftpos; - struct filelist filelist; - FILE *outfp = NULL; - - setlocale(LC_ALL, ""); - - memset(fldtab, 0, (ND+2)*sizeof(struct field)); - memset(d_mask, 0, NBINS); - d_mask[REC_D = '\n'] = REC_D_F; - SINGL_FLD = SEP_FLAG = 0; - d_mask['\t'] = d_mask[' '] = BLANK | FLD_D; - ftpos = fldtab; - many_files(); - - fixit(&argc, argv); - if (!(tmpdir = getenv("TMPDIR"))) - tmpdir = _PATH_TMP; - - while ((ch = getopt(argc, argv, "bcdfik:mHno:rR:sSt:T:ux")) != -1) { - switch (ch) { - case 'b': - fldtab->flags |= BI | BT; - break; - case 'c': - cflag = 1; - break; - case 'd': case 'f': case 'i': case 'n': case 'r': - tmp |= optval(ch, 0); - if ((tmp & R) && (tmp & F)) - fldtab->weights = RFtable; - else if (tmp & F) - fldtab->weights = Ftable; - else if (tmp & R) - fldtab->weights = Rascii; - fldtab->flags |= tmp; - break; - case 'H': - PANIC = 0; - break; - case 'k': - setfield(optarg, ++ftpos, fldtab->flags); - break; - case 'm': - mflag = 1; - break; - case 'o': - outpath = optarg; - break; - case 's': - /* for GNU sort compatibility (this is our default) */ - stable_sort = 1; - break; - case 'S': - stable_sort = 0; - break; - case 't': - if (SEP_FLAG) - usage("multiple field delimiters"); - SEP_FLAG = 1; - d_mask[' '] &= ~FLD_D; - d_mask['\t'] &= ~FLD_D; - d_mask[(u_char)*optarg] |= FLD_D; - if (d_mask[(u_char)*optarg] & REC_D_F) - errx(2, "record/field delimiter clash"); - break; - case 'R': - if (REC_D != '\n') - usage("multiple record delimiters"); - if ('\n' == (REC_D = *optarg)) - break; - d_mask['\n'] = d_mask[' ']; - d_mask[REC_D] = REC_D_F; - break; - case 'T': - /* -T tmpdir */ - tmpdir = optarg; - break; - case 'u': - UNIQUE = 1; - break; - case '?': - default: - usage(NULL); - } - } - if (cflag && argc > optind+1) - errx(2, "too many input files for -c option"); - if (argc - 2 > optind && !strcmp(argv[argc-2], "-o")) { - outpath = argv[argc-1]; - argc -= 2; - } - if (mflag && argc - optind > (MAXFCT - (16+1))*16) - errx(2, "too many input files for -m option"); - for (i = optind; i < argc; i++) { - /* allow one occurrence of /dev/stdin */ - if (!strcmp(argv[i], "-") || !strcmp(argv[i], _PATH_STDIN)) { - if (stdinflag) - warnx("ignoring extra \"%s\" in file list", - argv[i]); - else - stdinflag = 1; - - /* change to /dev/stdin if '-' */ - if (argv[i][0] == '-') - argv[i] = _PATH_STDIN; - - } else if ((ch = access(argv[i], R_OK))) - err(2, "%s", argv[i]); - } - if (!(fldtab->flags & (I|D|N) || fldtab[1].icol.num)) { - SINGL_FLD = 1; - fldtab[0].icol.num = 1; - } else { - if (!fldtab[1].icol.num) { - fldtab[0].flags &= ~(BI|BT); - setfield("1", ++ftpos, fldtab->flags); - } - fldreset(fldtab); - fldtab[0].flags &= ~F; - } - settables(fldtab[0].flags); - num_init(); - fldtab->weights = gweights; - if (optind == argc) { - static const char * const names[] = { _PATH_STDIN, NULL }; - - filelist.names = names; - optind--; - } else - filelist.names = (const char * const *) &argv[optind]; - - if (SINGL_FLD) - get = makeline; - else - get = makekey; - - if (cflag) { - order(&filelist, get, fldtab); - /* NOT REACHED */ - } - if (!outpath) { - (void)snprintf(toutpath, - sizeof(toutpath), "%sstdout", _PATH_DEV); - outfile = outpath = toutpath; - outfp = stdout; - } else if (!(ch = access(outpath, 0)) && - strncmp(_PATH_DEV, outpath, 5)) { - static const struct sigaction act = - { onsignal, {{0}}, SA_RESTART | SA_RESETHAND }; - static const int sigtable[] = {SIGHUP, SIGINT, SIGPIPE, - SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, 0}; - int outfd; - errno = 0; - if (access(outpath, W_OK)) - err(2, "%s", outpath); - (void)snprintf(toutpath, sizeof(toutpath), "%sXXXXXX", - outpath); - if ((outfd = mkstemp(toutpath)) == -1) - err(2, "Cannot create temporary file `%s'", toutpath); - if ((outfp = fdopen(outfd, "w")) == NULL) - err(2, "Cannot open temporary file `%s'", toutpath); - outfile = toutpath; - (void)atexit(cleanup); - for (i = 0; sigtable[i]; ++i) /* always unlink toutpath */ - sigaction(sigtable[i], &act, 0); - } else - outfile = outpath; - - if (outfp == NULL && (outfp = fopen(outfile, "w")) == NULL) - err(2, "output file %s", outfile); - - if (mflag) { - fmerge(-1, 0, &filelist, argc-optind, get, outfp, putline, - fldtab); - } else - fsort(-1, 0, 0, &filelist, argc-optind, outfp, fldtab); - - if (outfile != outpath) { - if (access(outfile, 0)) - err(2, "%s", outfile); - (void)unlink(outpath); - if (link(outfile, outpath)) - err(2, "cannot link %s: output left in %s", - outpath, outfile); - (void)unlink(outfile); - } - exit(0); -} - -static void -onsignal(sig) - int sig; -{ - cleanup(); -} - -static void -cleanup() -{ - if (toutpath[0]) - (void)unlink(toutpath); -} - -static void -usage(msg) - const char *msg; -{ - if (msg != NULL) - (void)fprintf(stderr, "sort: %s\n", msg); - (void)fprintf(stderr, "usage: [-o output] [-cmubdfinrsS] [-t char] "); - (void)fprintf(stderr, "[-R char] [-k keydef] ... [files]\n"); - exit(2); -} - -static void -many_files() -{ -#if 0 - struct rlimit rlp_many_files[1]; - - if (getrlimit(RLIMIT_NOFILE, rlp_many_files) == 0) { - rlp_many_files->rlim_cur = rlp_many_files->rlim_max; - setrlimit(RLIMIT_NOFILE, rlp_many_files); - } -#endif -} diff --git a/usr.bin/sort/sort.h b/usr.bin/sort/sort.h deleted file mode 100644 index 6e1169f8d4d8..000000000000 --- a/usr.bin/sort/sort.h +++ /dev/null @@ -1,149 +0,0 @@ -/* $NetBSD: sort.h,v 1.11 2001/01/19 10:14:31 jdolecek Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Peter McIlroy. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)sort.h 8.1 (Berkeley) 6/6/93 - */ - -#include <sys/param.h> - -#include <db.h> -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#define NBINS 256 -#define MAXMERGE 16 - -/* values for masks, weights, and other flags. */ -#define I 1 /* mask out non-printable characters */ -#define D 2 /* sort alphanumeric characters only */ -#define N 4 /* Field is a number */ -#define F 8 /* weight lower and upper case the same */ -#define R 16 /* Field is reversed with respect to the global weight */ -#define BI 32 /* ignore blanks in icol */ -#define BT 64 /* ignore blanks in tcol */ - -/* masks for delimiters: blanks, fields, and termination. */ -#define BLANK 1 /* ' ', '\t'; '\n' if -T is invoked */ -#define FLD_D 2 /* ' ', '\t' default; from -t otherwise */ -#define REC_D_F 4 /* '\n' default; from -T otherwise */ - -#define ND 10 /* limit on number of -k options. */ - -#define min(a, b) ((a) < (b) ? (a) : (b)) -#define max(a, b) ((a) > (b) ? (a) : (b)) - -#define FCLOSE(file) { \ - if (EOF == fclose(file)) \ - err(2, "%p", file); \ -} - -#define EWRITE(ptr, size, n, f) { \ - if (!fwrite(ptr, size, n, f)) \ - err(2, NULL); \ -} - -/* length of record is currently limited to maximum string length (size_t) */ -typedef size_t length_t; - -/* a record is a key/line pair starting at rec.data. It has a total length - * and an offset to the start of the line half of the pair. - */ -typedef struct recheader { - length_t length; - length_t offset; - u_char data[1]; -} RECHEADER; - -typedef struct trecheader { - length_t length; - length_t offset; -} TRECHEADER; - -/* This is the column as seen by struct field. It is used by enterfield. - * They are matched with corresponding coldescs during initialization. - */ -struct column { - struct coldesc *p; - int num; - int indent; -}; - -/* a coldesc has a number and pointers to the beginning and end of the - * corresponding column in the current line. This is determined in enterkey. - */ -typedef struct coldesc { - u_char *start; - u_char *end; - int num; -} COLDESC; - -/* A field has an initial and final column; an omitted final column - * implies the end of the line. Flags regulate omission of blanks and - * numerical sorts; mask determines which characters are ignored (from -i, -d); - * weights determines the sort weights of a character (from -f, -r). - */ -struct field { - struct column icol; - struct column tcol; - u_int flags; - u_char *mask; - u_char *weights; -}; - -struct filelist { - const char * const * names; -}; - -typedef int (*get_func_t) __P((int, int, struct filelist *, int, - RECHEADER *, u_char *, struct field *)); -typedef void (*put_func_t) __P((const struct recheader *, FILE *)); - -extern int PANIC; /* maximum depth of fsort before fmerge is called */ -extern u_char ascii[NBINS], Rascii[NBINS], Ftable[NBINS], RFtable[NBINS]; -extern u_char d_mask[NBINS]; -extern int SINGL_FLD, SEP_FLAG, UNIQUE; -extern int REC_D; -extern const char *tmpdir; -extern int stable_sort; -extern u_char gweights[NBINS]; - -#include "extern.h" diff --git a/usr.bin/sort/tmp.c b/usr.bin/sort/tmp.c deleted file mode 100644 index 55ca383dc58c..000000000000 --- a/usr.bin/sort/tmp.c +++ /dev/null @@ -1,84 +0,0 @@ -/* $NetBSD: tmp.c,v 1.7 2001/02/19 15:45:45 jdolecek Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Peter McIlroy. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <ctype.h> - -#ifndef lint -__RCSID("$NetBSD: tmp.c,v 1.7 2001/02/19 15:45:45 jdolecek Exp $"); -__SCCSID("@(#)tmp.c 8.1 (Berkeley) 6/6/93"); -#endif /* not lint */ - -#include <sys/param.h> - -#include <err.h> -#include <errno.h> -#include <limits.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "sort.h" -#include "pathnames.h" - -#define _NAME_TMP "sort.XXXXXXXX" - -FILE * -ftmp() -{ - sigset_t set, oset; - FILE *fp; - int fd; - char pathb[MAXPATHLEN], *path; - - path = pathb; - (void)snprintf(path, sizeof(pathb), "%s%s%s", tmpdir, - (tmpdir[strlen(tmpdir)-1] != '/') ? "/" : "", _NAME_TMP); - - sigfillset(&set); - (void)sigprocmask(SIG_BLOCK, &set, &oset); - if ((fd = mkstemp(path)) < 0) - err(2, "ftmp: mkstemp(\"%s\")", path); - if (!(fp = fdopen(fd, "w+"))) - err(2, "ftmp: fdopen(\"%s\")", path); - (void)unlink(path); - - (void)sigprocmask(SIG_SETMASK, &oset, NULL); - return (fp); -} diff --git a/usr.bin/stat/Makefile b/usr.bin/stat/Makefile deleted file mode 100644 index 0c95721859c0..000000000000 --- a/usr.bin/stat/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $FreeBSD$ - -PROG= stat -MAN= stat.1 -SRCS= stat.c -WARNS?= 2 - -.include <bsd.prog.mk> diff --git a/usr.bin/stat/stat.1 b/usr.bin/stat/stat.1 deleted file mode 100644 index cd238233e1f3..000000000000 --- a/usr.bin/stat/stat.1 +++ /dev/null @@ -1,434 +0,0 @@ -.\" $NetBSD: stat.1,v 1.4 2002/05/09 17:52:03 atatat Exp $ -.\" -.\" Copyright (c) 2002 The NetBSD Foundation, Inc. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to The NetBSD Foundation -.\" by Andrew Brown and Jan Schaumann. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the NetBSD -.\" Foundation, Inc. and its contributors. -.\" 4. Neither the name of The NetBSD Foundation 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 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. -.\" -.\" $FreeBSD$ -.\" -.Dd April 24, 2002 -.Dt STAT 1 -.Os -.Sh NAME -.Nm stat -.Nd display file status -.Sh SYNOPSIS -.Nm -.Op Fl FLn -.Oo -.Fl f Ar format | -.Fl l | -.Fl r | -.Fl s | -.Fl x -.Oc -.Op Fl t Ar timefmt -.Op Ar -.Sh DESCRIPTION -The -.Nm -utility displays information about the file pointed to by -.Ar file . -Read, write or execute permissions of the named file are not required, but -all directories listed in the path name leading to the file must be -searchable. If no argument is given, -.Nm -displays information about the file descriptor for standard input. -.Pp -The information displayed is obtained by calling -.Xr lstat 2 -with the given argument and evaluating the returned structure. -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl F -As in -.Ic ls , -display a slash (/) immediately after each pathname that is a directory, an -asterisk (*) after each that is executable, an at sign (@) after each symbolic -link, a percent sign (%) after each whiteout, an equal sign (=) after each -socket, and a vertical bar (|) after each that is a FIFO. The use of -.Fl F -implies -.Fl l . -.It Fl L -Use -.Xr stat 2 -instead of -.Xr lstat 2 . -The information reported by -.Nm -will refer to the target of -.Ar file , -if file is a symbolic link, and not to -.Ar file -itself. -.It Fl n -Do not force a newline to appear at the end of each piece of output. -.It Fl f Ar format -Display information using the specified format. See the FORMATS section -for a description of valid formats. -.It Fl l -Display output in -.Ic ls Fl lT -format. -.It Fl r -Display raw information. That is, for all the fields in the stat-structure, -display the raw, numerical value (for example, times in seconds since the -epoch, etc.) -.It Fl s -Display information in ``shell output'', suitable for initializing variables. -.It Fl x -Display information in a more verbose way as known from some Linux -distributions. -.It Fl t Ar timefmt -Display timestamps using the specified format. This format is -passed directly to -.Xr strftime 3 . -.El -.Ss FORMATS -Format strings are similar to -.Xr printf 3 -formats in that they start with -.Cm % , -are then followed by a sequence of formatting characters, and end in -a character that selects the field of the struct stat which is to be -formatted. If the -.Cm % -is immediately followed by one of -.Cm n , -.Cm t , -.Cm % , -or -.Cm @ , -then a newline character, a tab character, a percent character, -or the current file number is printed, otherwise the string is -examined for the following: -.Pp -Any of the following optional flags: -.Bl -tag -width Ds -.It Cm # -Selects an alternate output form for octal and hexadecimal output. -Non-zero octal output will have a leading zero, and non-zero -hexadecimal output will have ``0x'' prepended to it. -.It Cm + -Asserts that a sign indicating whether a number is positive or negative -should always be printed. Non-negative numbers are not usually printed -with a sign. -.It Cm - -Aligns string output to the left of the field, instead of to the right. -.It Cm 0 -Sets the fill character for left padding to the 0 character, instead of -a space. -.It space -Reserves a space at the front of non-negative signed output fields. A -.Sq Cm + -overrides a space if both are used. -.El -.Pp -Then the following fields: -.Bl -tag -width Ds -.It Cm size -An optional decimal digit string specifying the minimum field width. -.It Cm prec -An optional precision composed of a decimal point -.Sq Cm \&. -and a decimal digit string that indicates the maximum string length, -the number of digits to appear after the decimal point in floating point -output, or the minimum number of digits to appear in numeric output. -.It Cm fmt -An optional output format specifier which is one of -.Cm D , -.Cm O , -.Cm U , -.Cm X , -.Cm F , -or -.Cm S . -These represent signed decimal output, octal output, unsigned decimal -output, hexadecimal output, floating point output, and string output, -respectively. Some output formats do not apply to all fields. -Floating point output only applies to timespec fields (the -.Cm a , -.Cm m , -and -.Cm c -fields). -.Pp -The special output specifier -.Cm S -may be used to indicate that the output, if -applicable, should be in string format. May be used in combination with -.Bl -tag -width Ds -.It Cm amc -Display date in strftime(3) format. -.It Cm dr -Display actual device name. -.It Cm gu -Display group or user name. -.It Cm p -Display the mode of -.Ar file -as in -.Ic ls -lTd . -.It Cm N -Displays the name of -.Ar file . -.It Cm T -Displays the type of -.Ar file . -.It Cm Y -Insert a `` -\*[Gt] '' into the output. Note that the default output format -for -.Cm Y -is a string, but if specified explicitly, these four characters are -prepended. -.El -.It Cm sub -An optional sub field specifier (high, middle, low). Only applies to -the -.Cm p , -.Cm d , -.Cm r , -and -.Cm T -output formats. It can be one of the following: -.Bl -tag -width Ds -.It Cm H -``High'' -- specifies the major number for devices from -.Cm r -or -.Cm d , -the ``user'' bits for permissions from the string form of -.Cm p , -the file ``type'' bits from the numeric forms of -.Cm p , -and the long output form of -.Cm T . -.It Cm L -``Low'' -- specifies the minor number for devices from -.Cm r -or -.Cm d , -the ``other'' bits for permissions from the string form of -.Cm p , -the ``user'', ``group'', and ``other'' bits from the numeric forms of -.Cm p , -and the -.Ic ls -F -style output character for file type when used with -.Cm T -(the use of -.Cm L -for this is optional). -.It Cm M -``Middle'' -- specifies the ``group'' bits for permissions from the -string output form of -.Cm p , -or the ``suid'', ``sgid'', and ``sticky'' bits for the numeric forms of -.Cm p . -.El -.It Cm datum -A required field specifier, being one of the following: -.Bl -tag -width Ds -.It Cm d -Device upon which -.Ar file -resides. -.It Cm i -.Ar file Ap s -inode number. -.It Cm p -File type and permissions. -.It Cm l -Number of hard links to -.Ar file . -.It Cm u , g -User-id and group-id of -.Ar file Ap s -owner. -.It Cm r -Device number for character and block device special files. -.It Cm a , m , c -The time -.Ar file -was last accessed, modified, or of when the inode was last changed. -.It Cm z -The size of -.Ar file -in bytes. -.It Cm b -Number of blocks allocated for -.Ar file . -.It Cm k -Optimal file system I/O operation block size. -.It Cm f -User defined flags for -.Ar file . -.It Cm v -Inode generation number. -.El -.Pp -The following four field specifiers are not drawn directly from the -data in struct stat, but are -.Bl -tag -width Ds -.It Cm N -The name of the file. -.It Cm T -The file type, either as in -.Ic ls -F -or in a more descriptive form if the sub field specifier -.Cm H -is given. -.It Cm Y -The target of a symbolic link. -.It Cm Z -Expands to ``major,minor'' from the rdev field for character or block -special devices and gives size output for all others. -.El -.El -.Pp -Only the -.Cm % -and the field specifier are required. Most field -specifiers default to -.Cm U -as an output form, with the -exception of -.Cm p -which defaults to -.Cm O , -.Cm a , m , -and -.Cm c -which default to -.Cm D , -and -.Cm Y , T , -and -.Cm N , -which default to -.Cm S . -.Sh EXIT STATUS -.Nm -exits 0 on success, and \*[Gt]0 if an error occurred. -.Sh EXAMPLES -Given a symbolic link ``foo'' that points from /tmp/foo to /, you would use -.Nm -as follows: -.Bd -literal -offset indent -\*[Gt] stat -F /tmp/foo -lrwxrwxrwx 1 jschauma cs 1 Apr 24 16:37:28 2002 /tmp/foo@ -\*[Gt] / - -\*[Gt] stat -LF /tmp/foo -lrwxrwxrwx 16 root wheel 512 Apr 19 10:57:54 2002 /tmp/foo/ -.Ed -.Pp -To initialize some shell-variables, you could use the -.Fl s -flag as follows: -.Bd -literal -offset indent -\*[Gt] csh -% eval set `stat -s .cshrc` -% echo $st_size $st_mtimespec -1148 1015432481 - -\*[Gt] sh -$ eval $(stat -s .profile) -$ echo $st_size $st_mtimespec -1148 1015432481 -.Ed -.Pp -In order to get a list of the kind of files including files pointed to if the -file is a symbolic link, you could use the following format: -.Bd -literal -offset indent -$ stat -f "%N: %HT%SY" /tmp/* -/tmp/bar: Symbolic Link -\*[Gt] /tmp/foo -/tmp/output25568: Regular File -/tmp/blah: Directory -/tmp/foo: Symbolic Link -\*[Gt] / -.Ed -.Pp -In order to get a list of the devices, their types and the major and minor -device numbers, formatted with tabs and linebreaks, you could use the -following format: -.Bd -literal -offset indent -stat -f "Name: %N%n%tType: %HT%n%tMajor: %Hr%n%tMinor: %Lr%n%n" /dev/* -[...] -Name: /dev/wt8 - Type: Block Device - Major: 3 - Minor: 8 - -Name: /dev/zero - Type: Character Device - Major: 2 - Minor: 12 -.Ed -.Pp -In order to determine the permissions set on a file separately, you could use -the following format: -.Bd -literal -offset indent -\*[Gt] stat -f "%Sp -\*[Gt] owner=%SHp group=%SMp other=%SLp" . -drwxr-xr-x -\*[Gt] owner=rwx group=r-x other=r-x -.Ed -.Pp -In order to determine the three files that have been modified most recently, -you could use the following format: -.Bd -literal -offset indent -\*[Gt] stat -f "%m%t%Sm %N" /tmp/* | sort -rn | head -3 | cut -f2- -Apr 25 11:47:00 2002 /tmp/blah -Apr 25 10:36:34 2002 /tmp/bar -Apr 24 16:47:35 2002 /tmp/foo -.Ed -.Sh SEE ALSO -.Xr file 1 , -.Xr ls 1 , -.Xr lstat 2 , -.Xr readlink 2 , -.Xr stat 2 , -.Xr printf 3 , -.Xr strftime 3 -.Sh HISTORY -The -.Nm -utility appeared in -.Nx 1.6 . -.Sh AUTHORS -The -.Nm -utility was written by Andrew Brown -.Aq atatat@netbsd.org . -This man page -was written by Jan Schaumann -.Aq jschauma@netbsd.org . diff --git a/usr.bin/stat/stat.c b/usr.bin/stat/stat.c deleted file mode 100644 index c41a8f0193e9..000000000000 --- a/usr.bin/stat/stat.c +++ /dev/null @@ -1,986 +0,0 @@ -/* $NetBSD: stat.c,v 1.13 2003/07/25 03:21:17 atatat Exp $ */ - -/* - * Copyright (c) 2002 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Andrew Brown. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation 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 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> -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: stat.c,v 1.13 2003/07/25 03:21:17 atatat Exp $"); -#endif - -#if HAVE_CONFIG_H -#include "config.h" -#else /* HAVE_CONFIG_H */ -#define HAVE_STRUCT_STAT_ST_FLAGS 1 -#define HAVE_STRUCT_STAT_ST_GEN 1 -#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1 -#define HAVE_STRUCT_STAT_ST_MTIMENSEC 1 -#define HAVE_DEVNAME 1 -#endif /* HAVE_CONFIG_H */ - -#include <sys/types.h> -#include <sys/stat.h> - -#include <ctype.h> -#include <err.h> -#include <grp.h> -#include <limits.h> -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> - -#if HAVE_STRUCT_STAT_ST_FLAGS -#define DEF_F "%#Xf " -#define RAW_F "%f " -#define SHELL_F " st_flags=%f" -#else /* HAVE_STRUCT_STAT_ST_FLAGS */ -#define DEF_F -#define RAW_F -#define SHELL_F -#endif /* HAVE_STRUCT_STAT_ST_FLAGS */ - -#if HAVE_STRUCT_STAT_ST_BIRTHTIME -#define DEF_B "\"%SB\" " -#define RAW_B "%B " -#define SHELL_B "st_birthtime=%B " -#else /* HAVE_STRUCT_STAT_ST_BIRTHTIME */ -#define DEF_B -#define RAW_B -#define SHELL_B -#endif /* HAVE_STRUCT_STAT_ST_BIRTHTIME */ - -#if HAVE_STRUCT_STAT_ST_ATIM -#define st_atimespec st_atim -#define st_ctimespec st_ctim -#define st_mtimespec st_mtim -#endif /* HAVE_STRUCT_STAT_ST_ATIM */ - -#define DEF_FORMAT \ - "%d %i %Sp %l %Su %Sg %r %z \"%Sa\" \"%Sm\" \"%Sc\" " DEF_B \ - "%k %b " DEF_F "%N" -#define RAW_FORMAT "%d %i %#p %l %u %g %r %z %a %m %c " RAW_B \ - "%k %b " RAW_F "%N" -#define LS_FORMAT "%Sp %l %Su %Sg %Z %Sm %N%SY" -#define LSF_FORMAT "%Sp %l %Su %Sg %Z %Sm %N%T%SY" -#define SHELL_FORMAT \ - "st_dev=%d st_ino=%i st_mode=%#p st_nlink=%l " \ - "st_uid=%u st_gid=%g st_rdev=%r st_size=%z " \ - "st_atime=%a st_mtime=%m st_ctime=%c " SHELL_B \ - "st_blksize=%k st_blocks=%b" SHELL_F -#define LINUX_FORMAT \ - " File: \"%N\"%n" \ - " Size: %-11z FileType: %HT%n" \ - " Mode: (%04OLp/%.10Sp) Uid: (%5u/%8Su) Gid: (%5g/%8Sg)%n" \ - "Device: %Hd,%Ld Inode: %i Links: %l%n" \ - "Access: %Sa%n" \ - "Modify: %Sm%n" \ - "Change: %Sc" - -#define TIME_FORMAT "%b %e %T %Y" - -#define FLAG_POUND 0x01 -#define FLAG_SPACE 0x02 -#define FLAG_PLUS 0x04 -#define FLAG_ZERO 0x08 -#define FLAG_MINUS 0x10 - -/* - * These format characters must all be unique, except the magic one. - */ -#define FMT_MAGIC '%' -#define FMT_DOT '.' - -#define SIMPLE_NEWLINE 'n' -#define SIMPLE_TAB 't' -#define SIMPLE_PERCENT '%' -#define SIMPLE_NUMBER '@' - -#define FMT_POUND '#' -#define FMT_SPACE ' ' -#define FMT_PLUS '+' -#define FMT_ZERO '0' -#define FMT_MINUS '-' - -#define FMT_DECIMAL 'D' -#define FMT_OCTAL 'O' -#define FMT_UNSIGNED 'U' -#define FMT_HEX 'X' -#define FMT_FLOAT 'F' -#define FMT_STRING 'S' - -#define FMTF_DECIMAL 0x01 -#define FMTF_OCTAL 0x02 -#define FMTF_UNSIGNED 0x04 -#define FMTF_HEX 0x08 -#define FMTF_FLOAT 0x10 -#define FMTF_STRING 0x20 - -#define HIGH_PIECE 'H' -#define MIDDLE_PIECE 'M' -#define LOW_PIECE 'L' - -#define SHOW_st_dev 'd' -#define SHOW_st_ino 'i' -#define SHOW_st_mode 'p' -#define SHOW_st_nlink 'l' -#define SHOW_st_uid 'u' -#define SHOW_st_gid 'g' -#define SHOW_st_rdev 'r' -#define SHOW_st_atime 'a' -#define SHOW_st_mtime 'm' -#define SHOW_st_ctime 'c' -#define SHOW_st_btime 'B' -#define SHOW_st_size 'z' -#define SHOW_st_blocks 'b' -#define SHOW_st_blksize 'k' -#define SHOW_st_flags 'f' -#define SHOW_st_gen 'v' -#define SHOW_symlink 'Y' -#define SHOW_filetype 'T' -#define SHOW_filename 'N' -#define SHOW_sizerdev 'Z' - -void usage(const char *); -void output(const struct stat *, const char *, - const char *, int, int, int); -int format1(const struct stat *, /* stat info */ - const char *, /* the file name */ - const char *, int, /* the format string itself */ - char *, size_t, /* a place to put the output */ - int, int, int, int, /* the parsed format */ - int, int); - -char *timefmt; -int linkfail; - -#define addchar(s, c, nl) \ - do { \ - (void)fputc((c), (s)); \ - (*nl) = ((c) == '\n'); \ - } while (0/*CONSTCOND*/) - -int -main(int argc, char *argv[]) -{ - struct stat st; - int ch, rc, errs, am_readlink; - int lsF, fmtchar, usestat, fn, nonl, quiet; - char *statfmt, *options, *synopsis; - - am_readlink = 0; - lsF = 0; - fmtchar = '\0'; - usestat = 0; - nonl = 0; - quiet = 0; - linkfail = 0; - statfmt = NULL; - timefmt = NULL; - - if (strcmp(getprogname(), "readlink") == 0) { - am_readlink = 1; - options = "n"; - synopsis = "[-n] [file ...]"; - statfmt = "%Y"; - fmtchar = 'f'; - quiet = 1; - } else { - options = "f:FlLnqrst:x"; - synopsis = "[-FlLnqrsx] [-f format] [-t timefmt] [file ...]"; - } - - while ((ch = getopt(argc, argv, options)) != -1) - switch (ch) { - case 'F': - lsF = 1; - break; - case 'L': - usestat = 1; - break; - case 'n': - nonl = 1; - break; - case 'q': - quiet = 1; - break; - case 'f': - statfmt = optarg; - /* FALLTHROUGH */ - case 'l': - case 'r': - case 's': - case 'x': - if (fmtchar != 0) - errx(1, "can't use format '%c' with '%c'", - fmtchar, ch); - fmtchar = ch; - break; - case 't': - timefmt = optarg; - break; - default: - usage(synopsis); - } - - argc -= optind; - argv += optind; - fn = 1; - - if (fmtchar == '\0') { - if (lsF) - fmtchar = 'l'; - else { - fmtchar = 'f'; - statfmt = DEF_FORMAT; - } - } - - if (lsF && fmtchar != 'l') - errx(1, "can't use format '%c' with -F", fmtchar); - - switch (fmtchar) { - case 'f': - /* statfmt already set */ - break; - case 'l': - statfmt = lsF ? LSF_FORMAT : LS_FORMAT; - break; - case 'r': - statfmt = RAW_FORMAT; - break; - case 's': - statfmt = SHELL_FORMAT; - break; - case 'x': - statfmt = LINUX_FORMAT; - if (timefmt == NULL) - timefmt = "%c"; - break; - default: - usage(synopsis); - /*NOTREACHED*/ - } - - if (timefmt == NULL) - timefmt = TIME_FORMAT; - - errs = 0; - do { - if (argc == 0) - rc = fstat(STDIN_FILENO, &st); - else if (usestat) - rc = stat(argv[0], &st); - else - rc = lstat(argv[0], &st); - - if (rc == -1) { - errs = 1; - linkfail = 1; - if (!quiet) - warn("%s: stat", - argc == 0 ? "(stdin)" : argv[0]); - } - else - output(&st, argv[0], statfmt, fn, nonl, quiet); - - argv++; - argc--; - fn++; - } while (argc > 0); - - return (am_readlink ? linkfail : errs); -} - -void -usage(const char *synopsis) -{ - - (void)fprintf(stderr, "usage: %s %s\n", getprogname(), synopsis); - exit(1); -} - -/* - * Parses a format string. - */ -void -output(const struct stat *st, const char *file, - const char *statfmt, int fn, int nonl, int quiet) -{ - int flags, size, prec, ofmt, hilo, what; - char buf[PATH_MAX]; - const char *subfmt; - int nl, t, i; - - nl = 1; - while (*statfmt != '\0') { - - /* - * Non-format characters go straight out. - */ - if (*statfmt != FMT_MAGIC) { - addchar(stdout, *statfmt, &nl); - statfmt++; - continue; - } - - /* - * The current format "substring" starts here, - * and then we skip the magic. - */ - subfmt = statfmt; - statfmt++; - - /* - * Some simple one-character "formats". - */ - switch (*statfmt) { - case SIMPLE_NEWLINE: - addchar(stdout, '\n', &nl); - statfmt++; - continue; - case SIMPLE_TAB: - addchar(stdout, '\t', &nl); - statfmt++; - continue; - case SIMPLE_PERCENT: - addchar(stdout, '%', &nl); - statfmt++; - continue; - case SIMPLE_NUMBER: { - char num[12], *p; - - snprintf(num, sizeof(num), "%d", fn); - for (p = &num[0]; *p; p++) - addchar(stdout, *p, &nl); - statfmt++; - continue; - } - } - - /* - * This must be an actual format string. Format strings are - * similar to printf(3) formats up to a point, and are of - * the form: - * - * % required start of format - * [-# +0] opt. format characters - * size opt. field width - * . opt. decimal separator, followed by - * prec opt. precision - * fmt opt. output specifier (string, numeric, etc.) - * sub opt. sub field specifier (high, middle, low) - * datum required field specifier (size, mode, etc) - * - * Only the % and the datum selector are required. All data - * have reasonable default output forms. The "sub" specifier - * only applies to certain data (mode, dev, rdev, filetype). - * The symlink output defaults to STRING, yet will only emit - * the leading " -> " if STRING is explicitly specified. The - * sizerdev datum will generate rdev output for character or - * block devices, and size output for all others. - */ - flags = 0; - do { - if (*statfmt == FMT_POUND) - flags |= FLAG_POUND; - else if (*statfmt == FMT_SPACE) - flags |= FLAG_SPACE; - else if (*statfmt == FMT_PLUS) - flags |= FLAG_PLUS; - else if (*statfmt == FMT_ZERO) - flags |= FLAG_ZERO; - else if (*statfmt == FMT_MINUS) - flags |= FLAG_MINUS; - else - break; - statfmt++; - } while (1/*CONSTCOND*/); - - size = -1; - if (isdigit((unsigned)*statfmt)) { - size = 0; - while (isdigit((unsigned)*statfmt)) { - size = (size * 10) + (*statfmt - '0'); - statfmt++; - if (size < 0) - goto badfmt; - } - } - - prec = -1; - if (*statfmt == FMT_DOT) { - statfmt++; - - prec = 0; - while (isdigit((unsigned)*statfmt)) { - prec = (prec * 10) + (*statfmt - '0'); - statfmt++; - if (prec < 0) - goto badfmt; - } - } - -#define fmtcase(x, y) case (y): (x) = (y); statfmt++; break -#define fmtcasef(x, y, z) case (y): (x) = (z); statfmt++; break - switch (*statfmt) { - fmtcasef(ofmt, FMT_DECIMAL, FMTF_DECIMAL); - fmtcasef(ofmt, FMT_OCTAL, FMTF_OCTAL); - fmtcasef(ofmt, FMT_UNSIGNED, FMTF_UNSIGNED); - fmtcasef(ofmt, FMT_HEX, FMTF_HEX); - fmtcasef(ofmt, FMT_FLOAT, FMTF_FLOAT); - fmtcasef(ofmt, FMT_STRING, FMTF_STRING); - default: - ofmt = 0; - break; - } - - switch (*statfmt) { - fmtcase(hilo, HIGH_PIECE); - fmtcase(hilo, MIDDLE_PIECE); - fmtcase(hilo, LOW_PIECE); - default: - hilo = 0; - break; - } - - switch (*statfmt) { - fmtcase(what, SHOW_st_dev); - fmtcase(what, SHOW_st_ino); - fmtcase(what, SHOW_st_mode); - fmtcase(what, SHOW_st_nlink); - fmtcase(what, SHOW_st_uid); - fmtcase(what, SHOW_st_gid); - fmtcase(what, SHOW_st_rdev); - fmtcase(what, SHOW_st_atime); - fmtcase(what, SHOW_st_mtime); - fmtcase(what, SHOW_st_ctime); - fmtcase(what, SHOW_st_btime); - fmtcase(what, SHOW_st_size); - fmtcase(what, SHOW_st_blocks); - fmtcase(what, SHOW_st_blksize); - fmtcase(what, SHOW_st_flags); - fmtcase(what, SHOW_st_gen); - fmtcase(what, SHOW_symlink); - fmtcase(what, SHOW_filetype); - fmtcase(what, SHOW_filename); - fmtcase(what, SHOW_sizerdev); - default: - goto badfmt; - } -#undef fmtcasef -#undef fmtcase - - t = format1(st, - file, - subfmt, statfmt - subfmt, - buf, sizeof(buf), - flags, size, prec, ofmt, hilo, what); - - for (i = 0; i < t && i < sizeof(buf); i++) - addchar(stdout, buf[i], &nl); - - continue; - - badfmt: - errx(1, "%.*s: bad format", - (int)(statfmt - subfmt + 1), subfmt); - } - - if (!nl && !nonl) - (void)fputc('\n', stdout); - (void)fflush(stdout); -} - -/* - * Arranges output according to a single parsed format substring. - */ -int -format1(const struct stat *st, - const char *file, - const char *fmt, int flen, - char *buf, size_t blen, - int flags, int size, int prec, int ofmt, - int hilo, int what) -{ - u_int64_t data; - char *sdata, lfmt[24], tmp[20]; - char smode[12], sid[12], path[PATH_MAX + 4]; - struct passwd *pw; - struct group *gr; - const struct timespec *tsp; - struct timespec ts; - struct tm *tm; - int l, small, formats; - - tsp = NULL; - formats = 0; - small = 0; - - /* - * First, pick out the data and tweak it based on hilo or - * specified output format (symlink output only). - */ - switch (what) { - case SHOW_st_dev: - case SHOW_st_rdev: - small = (sizeof(st->st_dev) == 4); - data = (what == SHOW_st_dev) ? st->st_dev : st->st_rdev; -#if HAVE_DEVNAME - sdata = (what == SHOW_st_dev) ? - devname(st->st_dev, S_IFBLK) : - devname(st->st_rdev, - S_ISCHR(st->st_mode) ? S_IFCHR : - S_ISBLK(st->st_mode) ? S_IFBLK : - 0U); - if (sdata == NULL) - sdata = "???"; -#endif /* HAVE_DEVNAME */ - if (hilo == HIGH_PIECE) { - data = major(data); - hilo = 0; - } - else if (hilo == LOW_PIECE) { - data = minor((unsigned)data); - hilo = 0; - } - formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX | -#if HAVE_DEVNAME - FMTF_STRING; -#else /* HAVE_DEVNAME */ - 0; -#endif /* HAVE_DEVNAME */ - if (ofmt == 0) - ofmt = FMTF_UNSIGNED; - break; - case SHOW_st_ino: - small = (sizeof(st->st_ino) == 4); - data = st->st_ino; - sdata = NULL; - formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX; - if (ofmt == 0) - ofmt = FMTF_UNSIGNED; - break; - case SHOW_st_mode: - small = (sizeof(st->st_mode) == 4); - data = st->st_mode; - strmode(st->st_mode, smode); - sdata = smode; - l = strlen(sdata); - if (sdata[l - 1] == ' ') - sdata[--l] = '\0'; - if (hilo == HIGH_PIECE) { - data >>= 12; - sdata += 1; - sdata[3] = '\0'; - hilo = 0; - } - else if (hilo == MIDDLE_PIECE) { - data = (data >> 9) & 07; - sdata += 4; - sdata[3] = '\0'; - hilo = 0; - } - else if (hilo == LOW_PIECE) { - data &= 0777; - sdata += 7; - sdata[3] = '\0'; - hilo = 0; - } - formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX | - FMTF_STRING; - if (ofmt == 0) - ofmt = FMTF_OCTAL; - break; - case SHOW_st_nlink: - small = (sizeof(st->st_dev) == 4); - data = st->st_nlink; - sdata = NULL; - formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX; - if (ofmt == 0) - ofmt = FMTF_UNSIGNED; - break; - case SHOW_st_uid: - small = (sizeof(st->st_uid) == 4); - data = st->st_uid; - if ((pw = getpwuid(st->st_uid)) != NULL) - sdata = pw->pw_name; - else { - snprintf(sid, sizeof(sid), "(%ld)", (long)st->st_uid); - sdata = sid; - } - formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX | - FMTF_STRING; - if (ofmt == 0) - ofmt = FMTF_UNSIGNED; - break; - case SHOW_st_gid: - small = (sizeof(st->st_gid) == 4); - data = st->st_gid; - if ((gr = getgrgid(st->st_gid)) != NULL) - sdata = gr->gr_name; - else { - snprintf(sid, sizeof(sid), "(%ld)", (long)st->st_gid); - sdata = sid; - } - formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX | - FMTF_STRING; - if (ofmt == 0) - ofmt = FMTF_UNSIGNED; - break; - case SHOW_st_atime: - tsp = &st->st_atimespec; - /* FALLTHROUGH */ - case SHOW_st_mtime: - if (tsp == NULL) - tsp = &st->st_mtimespec; - /* FALLTHROUGH */ - case SHOW_st_ctime: - if (tsp == NULL) - tsp = &st->st_ctimespec; - /* FALLTHROUGH */ -#if HAVE_STRUCT_STAT_ST_BIRTHTIME - case SHOW_st_btime: - if (tsp == NULL) - tsp = &st->st_birthtimespec; -#endif /* HAVE_STRUCT_STAT_ST_BIRTHTIME */ - ts = *tsp; /* copy so we can muck with it */ - small = (sizeof(ts.tv_sec) == 4); - data = ts.tv_sec; - small = 1; - tm = localtime(&ts.tv_sec); - (void)strftime(path, sizeof(path), timefmt, tm); - sdata = path; - formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX | - FMTF_FLOAT | FMTF_STRING; - if (ofmt == 0) - ofmt = FMTF_DECIMAL; - break; - case SHOW_st_size: - small = (sizeof(st->st_size) == 4); - data = st->st_size; - sdata = NULL; - formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX; - if (ofmt == 0) - ofmt = FMTF_UNSIGNED; - break; - case SHOW_st_blocks: - small = (sizeof(st->st_blocks) == 4); - data = st->st_blocks; - sdata = NULL; - formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX; - if (ofmt == 0) - ofmt = FMTF_UNSIGNED; - break; - case SHOW_st_blksize: - small = (sizeof(st->st_blksize) == 4); - data = st->st_blksize; - sdata = NULL; - formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX; - if (ofmt == 0) - ofmt = FMTF_UNSIGNED; - break; -#if HAVE_STRUCT_STAT_ST_FLAGS - case SHOW_st_flags: - small = (sizeof(st->st_flags) == 4); - data = st->st_flags; - sdata = NULL; - formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX; - if (ofmt == 0) - ofmt = FMTF_UNSIGNED; - break; -#endif /* HAVE_STRUCT_STAT_ST_FLAGS */ -#if HAVE_STRUCT_STAT_ST_GEN - case SHOW_st_gen: - small = (sizeof(st->st_gen) == 4); - data = st->st_gen; - sdata = NULL; - formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX; - if (ofmt == 0) - ofmt = FMTF_UNSIGNED; - break; -#endif /* HAVE_STRUCT_STAT_ST_GEN */ - case SHOW_symlink: - small = 0; - data = 0; - if (S_ISLNK(st->st_mode)) { - snprintf(path, sizeof(path), " -> "); - l = readlink(file, path + 4, sizeof(path) - 4 - 1); - if (l == -1) { - linkfail = 1; - l = 0; - path[0] = '\0'; - } - path[l + 4] = '\0'; - sdata = path + (ofmt == FMTF_STRING ? 0 : 4); - } - else { - linkfail = 1; - sdata = ""; - } - formats = FMTF_STRING; - if (ofmt == 0) - ofmt = FMTF_STRING; - break; - case SHOW_filetype: - small = 0; - data = 0; - sdata = smode; - sdata[0] = '\0'; - if (hilo == 0 || hilo == LOW_PIECE) { - switch (st->st_mode & S_IFMT) { - case S_IFIFO: (void)strcat(sdata, "|"); break; - case S_IFDIR: (void)strcat(sdata, "/"); break; - case S_IFREG: - if (st->st_mode & - (S_IXUSR | S_IXGRP | S_IXOTH)) - (void)strcat(sdata, "*"); - break; - case S_IFLNK: (void)strcat(sdata, "@"); break; - case S_IFSOCK: (void)strcat(sdata, "="); break; -#ifdef S_IFWHT - case S_IFWHT: (void)strcat(sdata, "%"); break; -#endif /* S_IFWHT */ -#ifdef S_IFDOOR - case S_IFDOOR: (void)strcat(sdata, ">"); break; -#endif /* S_IFDOOR */ - } - hilo = 0; - } - else if (hilo == HIGH_PIECE) { - switch (st->st_mode & S_IFMT) { - case S_IFIFO: sdata = "Fifo File"; break; - case S_IFCHR: sdata = "Character Device"; break; - case S_IFDIR: sdata = "Directory"; break; - case S_IFBLK: sdata = "Block Device"; break; - case S_IFREG: sdata = "Regular File"; break; - case S_IFLNK: sdata = "Symbolic Link"; break; - case S_IFSOCK: sdata = "Socket"; break; -#ifdef S_IFWHT - case S_IFWHT: sdata = "Whiteout File"; break; -#endif /* S_IFWHT */ -#ifdef S_IFDOOR - case S_IFDOOR: sdata = "Door"; break; -#endif /* S_IFDOOR */ - default: sdata = "???"; break; - } - hilo = 0; - } - formats = FMTF_STRING; - if (ofmt == 0) - ofmt = FMTF_STRING; - break; - case SHOW_filename: - small = 0; - data = 0; - if (file == NULL) - (void)strncpy(path, "(stdin)", sizeof(path)); - else - (void)strncpy(path, file, sizeof(path)); - sdata = path; - formats = FMTF_STRING; - if (ofmt == 0) - ofmt = FMTF_STRING; - break; - case SHOW_sizerdev: - if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) { - char majdev[20], mindev[20]; - int l1, l2; - - l1 = format1(st, - file, - fmt, flen, - majdev, sizeof(majdev), - flags, size, prec, - ofmt, HIGH_PIECE, SHOW_st_rdev); - l2 = format1(st, - file, - fmt, flen, - mindev, sizeof(mindev), - flags, size, prec, - ofmt, LOW_PIECE, SHOW_st_rdev); - return (snprintf(buf, blen, "%.*s,%.*s", - l1, majdev, l2, mindev)); - } - else { - return (format1(st, - file, - fmt, flen, - buf, blen, - flags, size, prec, - ofmt, 0, SHOW_st_size)); - } - /*NOTREACHED*/ - default: - errx(1, "%.*s: bad format", (int)flen, fmt); - } - - /* - * If a subdatum was specified but not supported, or an output - * format was selected that is not supported, that's an error. - */ - if (hilo != 0 || (ofmt & formats) == 0) - errx(1, "%.*s: bad format", (int)flen, fmt); - - /* - * Assemble the format string for passing to printf(3). - */ - lfmt[0] = '\0'; - (void)strcat(lfmt, "%"); - if (flags & FLAG_POUND) - (void)strcat(lfmt, "#"); - if (flags & FLAG_SPACE) - (void)strcat(lfmt, " "); - if (flags & FLAG_PLUS) - (void)strcat(lfmt, "+"); - if (flags & FLAG_MINUS) - (void)strcat(lfmt, "-"); - if (flags & FLAG_ZERO) - (void)strcat(lfmt, "0"); - - /* - * Only the timespecs support the FLOAT output format, and that - * requires work that differs from the other formats. - */ - if (ofmt == FMTF_FLOAT) { - /* - * Nothing after the decimal point, so just print seconds. - */ - if (prec == 0) { - if (size != -1) { - (void)snprintf(tmp, sizeof(tmp), "%d", size); - (void)strcat(lfmt, tmp); - } - (void)strcat(lfmt, "d"); - return (snprintf(buf, blen, lfmt, ts.tv_sec)); - } - - /* - * Unspecified precision gets all the precision we have: - * 9 digits. - */ - if (prec == -1) - prec = 9; - - /* - * Adjust the size for the decimal point and the digits - * that will follow. - */ - size -= prec + 1; - - /* - * Any leftover size that's legitimate will be used. - */ - if (size > 0) { - (void)snprintf(tmp, sizeof(tmp), "%d", size); - (void)strcat(lfmt, tmp); - } - (void)strcat(lfmt, "d"); - - /* - * The stuff after the decimal point always needs zero - * filling. - */ - (void)strcat(lfmt, ".%0"); - - /* - * We can "print" at most nine digits of precision. The - * rest we will pad on at the end. - */ - (void)snprintf(tmp, sizeof(tmp), "%dd", prec > 9 ? 9 : prec); - (void)strcat(lfmt, tmp); - - /* - * For precision of less that nine digits, trim off the - * less significant figures. - */ - for (; prec < 9; prec++) - ts.tv_nsec /= 10; - - /* - * Use the format, and then tack on any zeroes that - * might be required to make up the requested precision. - */ - l = snprintf(buf, blen, lfmt, ts.tv_sec, ts.tv_nsec); - for (; prec > 9 && l < blen; prec--, l++) - (void)strcat(buf, "0"); - return (l); - } - - /* - * Add on size and precision, if specified, to the format. - */ - if (size != -1) { - (void)snprintf(tmp, sizeof(tmp), "%d", size); - (void)strcat(lfmt, tmp); - } - if (prec != -1) { - (void)snprintf(tmp, sizeof(tmp), ".%d", prec); - (void)strcat(lfmt, tmp); - } - - /* - * String output uses the temporary sdata. - */ - if (ofmt == FMTF_STRING) { - if (sdata == NULL) - errx(1, "%.*s: bad format", (int)flen, fmt); - (void)strcat(lfmt, "s"); - return (snprintf(buf, blen, lfmt, sdata)); - } - - /* - * Ensure that sign extension does not cause bad looking output - * for some forms. - */ - if (small && ofmt != FMTF_DECIMAL) - data = (u_int32_t)data; - - /* - * The four "numeric" output forms. - */ - (void)strcat(lfmt, "ll"); - switch (ofmt) { - case FMTF_DECIMAL: (void)strcat(lfmt, "d"); break; - case FMTF_OCTAL: (void)strcat(lfmt, "o"); break; - case FMTF_UNSIGNED: (void)strcat(lfmt, "u"); break; - case FMTF_HEX: (void)strcat(lfmt, "x"); break; - } - - return (snprintf(buf, blen, lfmt, data)); -} diff --git a/usr.bin/units/Makefile b/usr.bin/units/Makefile deleted file mode 100644 index 15679b5a7ce0..000000000000 --- a/usr.bin/units/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# $Id: Makefile,v 1.2 1996/04/06 06:00:58 thorpej Exp $ - -PROG= units - -beforeinstall: - install -c -o ${BINOWN} -g ${BINGRP} -m 444 \ - ${.CURDIR}/units.lib ${DESTDIR}/usr/share/misc - -.include <bsd.prog.mk> diff --git a/usr.bin/units/README b/usr.bin/units/README deleted file mode 100644 index ffb88a993165..000000000000 --- a/usr.bin/units/README +++ /dev/null @@ -1,18 +0,0 @@ -# $Id: README,v 1.2 1996/04/06 06:00:59 thorpej Exp $ - -This is a program which I wrote as a clone of the UNIX 'units' -command. I threw it together in a couple days, but it seems to work, -with some restrictions. I have tested it under DOS with Borland C and -Ultrix 4.2, and SunOS 4.1. - -This program differs from the unix units program in the following -ways: - it can gracefully handle exponents larger than 9 in output - it uses 'e' to denote exponentiation in numbers - prefixes are listed in the units file - it tries both -s and -es plurals - it allows use of * for multiply and ^ for exponentiation in the input - the output format is somewhat different - -Adrian Mariano (adrian@cam.cornell.edu or mariano@geom.umn.edu) - diff --git a/usr.bin/units/pathnames.h b/usr.bin/units/pathnames.h deleted file mode 100644 index b315c5b5823b..000000000000 --- a/usr.bin/units/pathnames.h +++ /dev/null @@ -1,33 +0,0 @@ -/* $Id: pathnames.h,v 1.3 1996/04/06 06:01:00 thorpej Exp $ */ - -/* - * Copyright (c) 1993 Christopher G. Demetriou - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christopher G. Demetriou. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * 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. - */ - -#define _PATH_UNITSLIB "/usr/share/misc/units.lib" diff --git a/usr.bin/units/units.1 b/usr.bin/units/units.1 deleted file mode 100644 index 891605247bfa..000000000000 --- a/usr.bin/units/units.1 +++ /dev/null @@ -1,124 +0,0 @@ -.\" $Id: units.1,v 1.6 1996/04/06 06:01:02 thorpej Exp $ -.TH UNITS 1 "14 July 1993" -.SH NAME -units - conversion program -.SH SYNTAX -.B units -[-f filename] [-qv] [from-unit to-unit] -.SH SUMMARY -.TP 4 -.B -f filename -Specifies the name of the units data file to load. -.LP -.TP 4 -.B -q -Suppresses prompting of the user for units and the display of statistics -about the number of units loaded. -.LP -.TP 4 -.B -v -Prints the version number. -.LP -.TP 4 -.B from-unit to-unit -Allows a single unit conversion to be done directly from the command -line. No prompting will occur. The units program will print out -only the result of this single conversion. - -.SH DESCRIPTION -The units program converts quantities expression in various scales to -their equivalents in other scales. The units program can only -handle multiplicative scale changes. It cannot convert Centigrade -to Fahrenheit, for example. It works interactively by prompting -the user for input: -.nf - - You have: meters - You want: feet - * 3.2808399 - / 0.3048 - - You have: cm^3 - You want: gallons - * 0.00026417205 - / 3785.4118 - -.fi -Powers of units can be specified using the '^' character as shown in -the example, or by simple concatenation: 'cm3' is equivalent to 'cm^3'. -Multiplication of units can be specified by using spaces, a dash or -an asterisk. Division of units is indicated by the slash ('/'). -Note that multiplication has a higher precedence than division, -so 'm/s/s' is the same as 'm/s^2' or 'm/s s'. -If the user enters incompatible unit types, the units program will -print a message indicating that the units are not conformable and -it will display the reduced form for each unit: -.nf - - You have: ergs/hour - You want: fathoms kg^2 / day - conformability error - 2.7777778e-11 kg m^2 / sec^3 - 2.1166667e-05 kg^2 m / sec - -.fi -.LP -The conversion information is read from a units data file. The default -file includes definitions for most familiar units, abbreviations and -metric prefixes. Some constants of nature included are: -.in +4m -.ta -.ta 9m + -.nf - -pi ratio of circumference to diameter -c speed of light -e charge on an electron -g acceleration of gravity -force same as g -mole Avogadro's number -water pressure per unit height of water -mercury pressure per unit height of mercury -au astronomical unit - -.fi -.in -4m -\'Pound' is a unit of mass. Compound names are run together -so 'poundforce' is a unit of force. British units that differ from their -US counterparts are prefixed with 'br', and currency is prefixed with -its country name: 'belgiumfranc', 'britainpound'. When searching for -a unit, if the specified string does not appear exactly as a unit -name, then the units program will try to remove a trailing 's' or -a trailing 'es' and check again for a match. -.LP -All of these definitions can be read in the standard units file, or you -can supply your own file. A unit is specified on a single line by -giving its name and an equivalence. One should be careful to define -new units in terms of old ones so that a reduction leads to the -primitive units which are marked with '!' characters. -The units program will not detect infinite loops that could be caused -by careless unit definitions. -.LP -Prefixes are defined in the same was as standard units, but with -a trailing dash at the end of the prefix name. -.SH BUGS -.LP -The effect of including a '/' in a prefix is surprising. -.LP -Exponents entered by the user can be only one digit. -You can work around this by multiplying several terms. -.LP -The user must use | to indicate division of numbers and / to -indicate division of symbols. This distinction should not -be necessary. -.LP -The program contains various arbitrary limits on the length -of the units converted and on the length of the data file. -.LP -The program should use a hash table to store units so that -it doesn't take so long to load the units list and check -for duplication. -.SH FILES -/usr/share/misc/units.lib - the standard units library -.SH AUTHOR -Adrian Mariano (adrian@cam.cornell.edu or mariano@geom.umn.edu) diff --git a/usr.bin/units/units.c b/usr.bin/units/units.c deleted file mode 100644 index 83e5b4223b22..000000000000 --- a/usr.bin/units/units.c +++ /dev/null @@ -1,706 +0,0 @@ -/* $Id: units.c,v 1.6 1996/04/06 06:01:03 thorpej Exp $ */ - -/* - * units.c Copyright (c) 1993 by Adrian Mariano (adrian@cam.cornell.edu) - * - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * Disclaimer: This software is provided by the author "as is". The author - * shall not be liable for any damages caused in any way by this software. - * - * I would appreciate (though I do not require) receiving a copy of any - * improvements you might make to this program. - */ - -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -#include "pathnames.h" - -#define VERSION "1.0" - -#ifndef UNITSFILE -#define UNITSFILE _PATH_UNITSLIB -#endif - -#define MAXUNITS 1000 -#define MAXPREFIXES 50 - -#define MAXSUBUNITS 500 - -#define PRIMITIVECHAR '!' - -char *powerstring = "^"; - -struct { - char *uname; - char *uval; -} unittable[MAXUNITS]; - -struct unittype { - char *numerator[MAXSUBUNITS]; - char *denominator[MAXSUBUNITS]; - double factor; -}; - -struct { - char *prefixname; - char *prefixval; -} prefixtable[MAXPREFIXES]; - - -char *NULLUNIT = ""; - -int unitcount; -int prefixcount; - - -char * -dupstr(char *str) -{ - char *ret; - - ret = malloc(strlen(str) + 1); - if (!ret) { - fprintf(stderr, "Memory allocation error\n"); - exit(3); - } - strcpy(ret, str); - return (ret); -} - - -void -readerror(int linenum) -{ - fprintf(stderr, "Error in units file '%s' line %d\n", UNITSFILE, - linenum); -} - - -void -readunits(char *userfile) -{ - FILE *unitfile; - char line[80], *lineptr; - int len, linenum, i; - - unitcount = 0; - linenum = 0; - - if (userfile) { - unitfile = fopen(userfile, "rt"); - if (!unitfile) { - fprintf(stderr, "Unable to open units file '%s'\n", - userfile); - exit(1); - } - } - else { - unitfile = fopen(UNITSFILE, "rt"); - if (!unitfile) { - char *direc, *env; - char filename[1000]; - char separator[2]; - - env = getenv("PATH"); - if (env) { - if (strchr(env, ';')) - strcpy(separator, ";"); - else - strcpy(separator, ":"); - direc = strtok(env, separator); - while (direc) { - strcpy(filename, ""); - strncat(filename, direc, 999); - strncat(filename, "/", - 999 - strlen(filename)); - strncat(filename, UNITSFILE, - 999 - strlen(filename)); - unitfile = fopen(filename, "rt"); - if (unitfile) - break; - direc = strtok(NULL, separator); - } - } - if (!unitfile) { - fprintf(stderr, "Can't find units file '%s'\n", - UNITSFILE); - exit(1); - } - } - } - while (!feof(unitfile)) { - if (!fgets(line, 79, unitfile)) - break; - linenum++; - lineptr = line; - if (*lineptr == '/') - continue; - lineptr += strspn(lineptr, " \n\t"); - len = strcspn(lineptr, " \n\t"); - lineptr[len] = 0; - if (!strlen(lineptr)) - continue; - if (lineptr[strlen(lineptr) - 1] == '-') { /* it's a prefix */ - if (prefixcount == MAXPREFIXES) { - fprintf(stderr, "Memory for prefixes exceeded in line %d\n", - linenum); - continue; - } - lineptr[strlen(lineptr) - 1] = 0; - prefixtable[prefixcount].prefixname = dupstr(lineptr); - for (i = 0; i < prefixcount; i++) - if (!strcmp(prefixtable[i].prefixname, lineptr)) { - fprintf(stderr, "Redefinition of prefix '%s' on line %d ignored\n", - lineptr, linenum); - continue; - } - lineptr += len + 1; - if (!strlen(lineptr)) { - readerror(linenum); - continue; - } - lineptr += strspn(lineptr, " \n\t"); - len = strcspn(lineptr, "\n\t"); - lineptr[len] = 0; - prefixtable[prefixcount++].prefixval = dupstr(lineptr); - } - else { /* it's not a prefix */ - if (unitcount == MAXUNITS) { - fprintf(stderr, "Memory for units exceeded in line %d\n", - linenum); - continue; - } - unittable[unitcount].uname = dupstr(lineptr); - for (i = 0; i < unitcount; i++) - if (!strcmp(unittable[i].uname, lineptr)) { - fprintf(stderr, "Redefinition of unit '%s' on line %d ignored\n", - lineptr, linenum); - continue; - } - lineptr += len + 1; - lineptr += strspn(lineptr, " \n\t"); - if (!strlen(lineptr)) { - readerror(linenum); - continue; - } - len = strcspn(lineptr, "\n\t"); - lineptr[len] = 0; - unittable[unitcount++].uval = dupstr(lineptr); - } - } - fclose(unitfile); -} - -void -initializeunit(struct unittype * theunit) -{ - theunit->factor = 1.0; - theunit->numerator[0] = theunit->denominator[0] = NULL; -} - - -int -addsubunit(char *product[], char *toadd) -{ - char **ptr; - - for (ptr = product; *ptr && *ptr != NULLUNIT; ptr++); - if (ptr >= product + MAXSUBUNITS) { - fprintf(stderr, "Memory overflow in unit reduction\n"); - return 1; - } - if (!*ptr) - *(ptr + 1) = 0; - *ptr = dupstr(toadd); - return 0; -} - - -void -showunit(struct unittype * theunit) -{ - char **ptr; - int printedslash; - int counter = 1; - - printf("\t%.8g", theunit->factor); - for (ptr = theunit->numerator; *ptr; ptr++) { - if (ptr > theunit->numerator && **ptr && - !strcmp(*ptr, *(ptr - 1))) - counter++; - else { - if (counter > 1) - printf("%s%d", powerstring, counter); - if (**ptr) - printf(" %s", *ptr); - counter = 1; - } - } - if (counter > 1) - printf("%s%d", powerstring, counter); - counter = 1; - printedslash = 0; - for (ptr = theunit->denominator; *ptr; ptr++) { - if (ptr > theunit->denominator && **ptr && - !strcmp(*ptr, *(ptr - 1))) - counter++; - else { - if (counter > 1) - printf("%s%d", powerstring, counter); - if (**ptr) { - if (!printedslash) - printf(" /"); - printedslash = 1; - printf(" %s", *ptr); - } - counter = 1; - } - } - if (counter > 1) - printf("%s%d", powerstring, counter); - printf("\n"); -} - - -void -zeroerror() -{ - fprintf(stderr, "Unit reduces to zero\n"); -} - -/* - Adds the specified string to the unit. - Flip is 0 for adding normally, 1 for adding reciprocal. - - Returns 0 for successful addition, nonzero on error. -*/ - -int -addunit(struct unittype * theunit, char *toadd, int flip) -{ - char *scratch, *savescr; - char *item; - char *divider, *slash; - int doingtop; - - savescr = scratch = dupstr(toadd); - for (slash = scratch + 1; *slash; slash++) - if (*slash == '-' && - (tolower(*(slash - 1)) != 'e' || - !strchr(".0123456789", *(slash + 1)))) - *slash = ' '; - slash = strchr(scratch, '/'); - if (slash) - *slash = 0; - doingtop = 1; - do { - item = strtok(scratch, " *\t\n/"); - while (item) { - if (strchr("0123456789.", *item)) { /* item is a number */ - double num; - - divider = strchr(item, '|'); - if (divider) { - *divider = 0; - num = atof(item); - if (!num) { - zeroerror(); - return 1; - } - if (doingtop ^ flip) - theunit->factor *= num; - else - theunit->factor /= num; - num = atof(divider + 1); - if (!num) { - zeroerror(); - return 1; - } - if (doingtop ^ flip) - theunit->factor /= num; - else - theunit->factor *= num; - } - else { - num = atof(item); - if (!num) { - zeroerror(); - return 1; - } - if (doingtop ^ flip) - theunit->factor *= num; - else - theunit->factor /= num; - - } - } - else { /* item is not a number */ - int repeat = 1; - - if (strchr("23456789", - item[strlen(item) - 1])) { - repeat = item[strlen(item) - 1] - '0'; - item[strlen(item) - 1] = 0; - } - for (; repeat; repeat--) - if (addsubunit(doingtop ^ flip ? theunit->numerator : theunit->denominator, item)) - return 1; - } - item = strtok(NULL, " *\t/\n"); - } - doingtop--; - if (slash) { - scratch = slash + 1; - } - else - doingtop--; - } while (doingtop >= 0); - free(savescr); - return 0; -} - - -int -compare(const void *item1, const void *item2) -{ - return strcmp(*(char **) item1, *(char **) item2); -} - - -void -sortunit(struct unittype * theunit) -{ - char **ptr; - int count; - - for (count = 0, ptr = theunit->numerator; *ptr; ptr++, count++); - qsort(theunit->numerator, count, sizeof(char *), compare); - for (count = 0, ptr = theunit->denominator; *ptr; ptr++, count++); - qsort(theunit->denominator, count, sizeof(char *), compare); -} - - -void -cancelunit(struct unittype * theunit) -{ - char **den, **num; - int comp; - - den = theunit->denominator; - num = theunit->numerator; - - while (*num && *den) { - comp = strcmp(*den, *num); - if (!comp) { -/* if (*den!=NULLUNIT) free(*den); - if (*num!=NULLUNIT) free(*num);*/ - *den++ = NULLUNIT; - *num++ = NULLUNIT; - } - else if (comp < 0) - den++; - else - num++; - } -} - - - - -/* - Looks up the definition for the specified unit. - Returns a pointer to the definition or a null pointer - if the specified unit does not appear in the units table. -*/ - -static char buffer[100]; /* buffer for lookupunit answers with - prefixes */ - -char * -lookupunit(char *unit) -{ - int i; - char *copy; - - for (i = 0; i < unitcount; i++) { - if (!strcmp(unittable[i].uname, unit)) - return unittable[i].uval; - } - - if (unit[strlen(unit) - 1] == '^') { - copy = dupstr(unit); - copy[strlen(copy) - 1] = 0; - for (i = 0; i < unitcount; i++) { - if (!strcmp(unittable[i].uname, copy)) { - strcpy(buffer, copy); - free(copy); - return buffer; - } - } - free(copy); - } - if (unit[strlen(unit) - 1] == 's') { - copy = dupstr(unit); - copy[strlen(copy) - 1] = 0; - for (i = 0; i < unitcount; i++) { - if (!strcmp(unittable[i].uname, copy)) { - strcpy(buffer, copy); - free(copy); - return buffer; - } - } - if (copy[strlen(copy) - 1] == 'e') { - copy[strlen(copy) - 1] = 0; - for (i = 0; i < unitcount; i++) { - if (!strcmp(unittable[i].uname, copy)) { - strcpy(buffer, copy); - free(copy); - return buffer; - } - } - } - free(copy); - } - for (i = 0; i < prefixcount; i++) { - if (!strncmp(prefixtable[i].prefixname, unit, - strlen(prefixtable[i].prefixname))) { - unit += strlen(prefixtable[i].prefixname); - if (!strlen(unit) || lookupunit(unit)) { - strcpy(buffer, prefixtable[i].prefixval); - strcat(buffer, " "); - strcat(buffer, unit); - return buffer; - } - } - } - return 0; -} - - - -/* - reduces a product of symbolic units to primitive units. - The three low bits are used to return flags: - - bit 0 (1) set on if reductions were performed without error. - bit 1 (2) set on if no reductions are performed. - bit 2 (4) set on if an unknown unit is discovered. -*/ - - -#define ERROR 4 - -int -reduceproduct(struct unittype * theunit, int flip) -{ - - char *toadd; - char **product; - int didsomething = 2; - - if (flip) - product = theunit->denominator; - else - product = theunit->numerator; - - for (; *product; product++) { - - for (;;) { - if (!strlen(*product)) - break; - toadd = lookupunit(*product); - if (!toadd) { - printf("unknown unit '%s'\n", *product); - return ERROR; - } - if (strchr(toadd, PRIMITIVECHAR)) - break; - didsomething = 1; - if (*product != NULLUNIT) { - free(*product); - *product = NULLUNIT; - } - if (addunit(theunit, toadd, flip)) - return ERROR; - } - } - return didsomething; -} - - -/* - Reduces numerator and denominator of the specified unit. - Returns 0 on success, or 1 on unknown unit error. -*/ - -int -reduceunit(struct unittype * theunit) -{ - int ret; - - ret = 1; - while (ret & 1) { - ret = reduceproduct(theunit, 0) | reduceproduct(theunit, 1); - if (ret & 4) - return 1; - } - return 0; -} - - -int -compareproducts(char **one, char **two) -{ - while (*one || *two) { - if (!*one && *two != NULLUNIT) - return 1; - if (!*two && *one != NULLUNIT) - return 1; - if (*one == NULLUNIT) - one++; - else if (*two == NULLUNIT) - two++; - else if (strcmp(*one, *two)) - return 1; - else - one++, two++; - } - return 0; -} - - -/* Return zero if units are compatible, nonzero otherwise */ - -int -compareunits(struct unittype * first, struct unittype * second) -{ - return - compareproducts(first->numerator, second->numerator) || - compareproducts(first->denominator, second->denominator); -} - - -int -completereduce(struct unittype * unit) -{ - if (reduceunit(unit)) - return 1; - sortunit(unit); - cancelunit(unit); - return 0; -} - - -void -showanswer(struct unittype * have, struct unittype * want) -{ - if (compareunits(have, want)) { - printf("conformability error\n"); - showunit(have); - showunit(want); - } - else - printf("\t* %.8g\n\t/ %.8g\n", have->factor / want->factor, - want->factor / have->factor); -} - - -void -usage() -{ - fprintf(stderr, "\nunits [-f unitsfile] [-q] [-v] [from-unit to-unit]\n"); - fprintf(stderr, "\n -f specify units file\n"); - fprintf(stderr, " -q supress prompting (quiet)\n"); - fprintf(stderr, " -v print version number\n"); - exit(3); -} - - -int -main(int argc, char **argv) -{ - - struct unittype have, want; - char havestr[81], wantstr[81]; - int optchar; - char *userfile = 0; - int quiet = 0; - - extern char *optarg; - extern int optind; - - while ((optchar = getopt(argc, argv, "vqf:")) != -1) { - switch (optchar) { - case 'f': - userfile = optarg; - break; - case 'q': - quiet = 1; - break; - case 'v': - fprintf(stderr, "\n units version %s Copyright (c) 1993 by Adrian Mariano\n", - VERSION); - fprintf(stderr, " This program may be freely distributed\n"); - usage(); - default: - usage(); - break; - } - } - - if (optind != argc - 2 && optind != argc) - usage(); - - readunits(userfile); - - if (optind == argc - 2) { - strcpy(havestr, argv[optind]); - strcpy(wantstr, argv[optind + 1]); - initializeunit(&have); - addunit(&have, havestr, 0); - completereduce(&have); - initializeunit(&want); - addunit(&want, wantstr, 0); - completereduce(&want); - showanswer(&have, &want); - } - else { - if (!quiet) - printf("%d units, %d prefixes\n\n", unitcount, - prefixcount); - for (;;) { - do { - initializeunit(&have); - if (!quiet) - printf("You have: "); - if (!fgets(havestr, 80, stdin)) { - if (!quiet); - putchar('\n'); - exit(0); - } - } while (addunit(&have, havestr, 0) || - completereduce(&have)); - do { - initializeunit(&want); - if (!quiet) - printf("You want: "); - if (!fgets(wantstr, 80, stdin)) { - if (!quiet) - putchar('\n'); - exit(0); - } - } while (addunit(&want, wantstr, 0) || - completereduce(&want)); - showanswer(&have, &want); - } - } -} diff --git a/usr.bin/units/units.lib b/usr.bin/units/units.lib deleted file mode 100644 index ef4e8d7a9a25..000000000000 --- a/usr.bin/units/units.lib +++ /dev/null @@ -1,610 +0,0 @@ -/ $Id: units.lib,v 1.3 1996/04/06 06:01:04 thorpej Exp $ - -/ primitive units - -m !a! -kg !b! -sec !c! -coul !d! -candela !e! -dollar !f! -bit !h! -erlang !i! -K !j! - -/ prefixes - -yotta- 1e24 -zetta- 1e21 -exa- 1e18 -peta- 1e15 -tera- 1e12 -giga- 1e9 -mega- 1e6 -myria- 1e4 -kilo- 1e3 -hecto- 1e2 -deka- 1e1 -deci- 1e-1 -centi- 1e-2 -milli- 1e-3 -micro- 1e-6 -nano- 1e-9 -pico- 1e-12 -femto- 1e-15 -atto- 1e-18 -zopto- 1e-21 -yocto- 1e-24 - -semi- .5 -demi- .5 - -Y- yotta -Z- zetta -E- exa -P- peta -T- tera -G- giga -M- mega -k- kilo -h- hecto -da- deka -d- deci -c- centi -m- milli -p- pico -f- femto -a- atto -z- zopto -y- yocto - -/ constants - -fuzz 1 -pi 3.14159265358979323846 -c 2.99792458e+8 m/sec fuzz -g 9.80665 m/sec2 -au 1.49597871e+11 m fuzz -mole 6.022169e+23 fuzz -e 1.6021917e-19 coul fuzz -energy c2 -force g -mercury 1.33322e+5 kg/m2-sec2 -hg mercury - -/ dimensionless - -radian .5 / pi -degree 1|180 pi-radian -circle 2 pi-radian -turn 2 pi-radian -revolution turn -rev turn -grade .9 degree -arcdeg 1 degree -arcmin 1|60 arcdeg -ccs 1|36 erlang -arcsec 1|60 arcmin - -steradian radian2 -sphere 4 pi-steradian -sr steradian - -/ Time - -second sec -s sec -minute 60 sec -min minute -hour 60 min -hr hour -day 24 hr -da day -week 7 day -year 365.24219879 day fuzz -yr year -month 1|12 year -ms millisec -us microsec - -/ Mass - -gram millikg -gm gram -mg milligram -metricton kilokg - -/ Avoirdupois - -lb .45359237 kg -pound lb -lbf lb g -ounce 1|16 lb -oz ounce -dram 1|16 oz -dr dram -grain 1|7000 lb -gr grain -shortton 2000 lb -ton shortton -longton 2240 lb - -/ Apothecary - -scruple 20 grain -apdram 60 grain -apounce 480 grain -appound 5760 grain -troypound appound - -/ Length - -meter m -cm centimeter -mm millimeter -km kilometer -nm nanometer -micron micrometer -angstrom decinanometer - -inch 2.54 cm -in inch -foot 12 in -feet foot -ft foot -yard 3 ft -yd yard -rod 5.5 yd -rd rod -mile 5280 ft -mi mile - -british 1200|3937 m/ft -nmile 1852 m - -acre 4840 yd2 - -cc cm3 -liter kilocc -ml milliliter - -/ US Liquid - -gallon 231 in3 -imperial 1.20095 -gal gallon -quart 1|4 gal -qt quart -pint 1|2 qt -pt pint - -floz 1|16 pt -fldr 1|8 floz - -/ US Dry - -dry 268.8025 in3/gallon fuzz -peck 8 dry-quart -pk peck -bushel 4 peck -bu bushel -chaldron 36 bushel - -/ British - -brgallon 277.420 in3 fuzz -brquart 1|4 brgallon -brpint 1|2 brquart -brfloz 1|20 brpint -brpeck 554.84 in3 fuzz -brbushel 4 brpeck - -/ Energy Work - -newton kg-m/sec2 -nt newton -N newton -joule nt-m -cal 4.1868 joule - -/ Electrical - -coulomb coul -C coul -ampere coul/sec -amp ampere -watt joule/sec -volt watt/amp -ohm volt/amp -mho /ohm -farad coul/volt -henry sec2/farad -weber volt-sec - -/ Light - -cd candela -lumen cd sr -lux cd sr/m2 - -/ Wall Street Journal, July 2, 1993 - -$ dollar -argentinapeso $ -australiadollar .66 $ -austriaschilling .83 $ -bahraindinar 2.6522 $ -belgiumfranc .028 $ -brazilcruzeiro .000019 $ -britainpound 1.49 $ -canadadollar .77 $ -czechkoruna .034 $ -chilepeso .0025 $ -chinarenminbi .174856 $ -colombiapeso .001495 $ -denmarkkrone .15 $ -ecuadorsucre .000539 $ -finlandmarkka .17 $ -francefranc .17 $ -germanymark .58 $ -greatbritainpound britainpound -greecedrachma .0043 $ -hongkongdollar .13 $ -hungaryforint .011 $ -indiarupee .03211 $ -indonesiarupiah .0004782 $ -irelandpunt 1.43 $ -israelshekel .3642 $ -italylira .00064 $ -japanyen .0093 $ -jordandinar 1.4682 $ -kuwaitdinar 3.3173 $ -lebanonpound .000578 $ -malaysiaringgit .338 $ -maltalira 2.6042 $ -mexicopeso .3205128 $ -netherlandguilder .52 $ -newzealanddollar .539 $ -norwaykrone .139 $ -pakistanrupee .037 $ -perunewsol .5065 $ -philippinespeso .03738 $ -polandzloty .000059 $ -portugalescudo .00617 $ -saudiarabiariyal .26702 $ -singaporedollar .6157 $ -slovakkoruna .034 $ -southamericarand .21 $ -southkoreawon .001 $ -spainpeseta .007 $ -swedenkrona .13 $ -switzerlandfranc .66 $ -taiwandollar .038285 $ -thailandbaht .03962 $ -turkeylira .0000929 $ -unitedarabdirham .2723 $ -uruguaynewpeso .246852 $ -venezuelabolivar .011 $ - -mark germanymark -bolivar venezuelabolivar -peseta spainpeseta -rand southafricarand -escudo portugalescudo -sol perusol -guilder netherlandsguilder -hollandguilder netherlandsguilder -peso mexicopeso -yen japanyen -lira italylira -rupee indiarupee -drachma greecedrachma -franc francefranc -markka finlandmarkka -sucre ecuadorsucre -poundsterling britainpound -cruzeiro brazilcruzeiro - -/ computer - -baud bit/sec -byte 8 bit -block 512 byte -kbyte 1024 byte -megabyte 1024 kbyte -gigabyte 1024 megabyte -meg megabyte - - -/ Trivia - -% 1|100 -admiraltyknot 6080 ft/hr -apostilb cd/pi-m2 -are 1e+2 m2 -arpentcan 27.52 mi -arpentlin 191.835 ft -astronomicalunit au -atmosphere 1.01325e+5 nt/m2 -atm atmosphere -atomicmassunit 1.66044e-27 kg fuzz -amu atomicmassunit -bag 94 lb -bakersdozen 13 -bar 1e+5 nt/m2 -barie 1e-1 nt/m2 -barleycorn 1|3 in -barn 1e-28 m2 -barrel 42 gal -barye 1e-1 nt/m2 -bev 1e+9 e-volt -biot 10 amp -blondel cd/pi-m2 -boardfoot 144 in3 -bolt 40 yd -bottommeasure 1|40 in -britishthermalunit 1.05506e+3 joule fuzz -btu britishthermalunit -refrigeration 12000 btu/ton-hour -buck dollar -cable 720 ft -caliber 1e-2 in -calorie cal -carat 205 mg -caratgold 1|24 -cent centidollar -cental 100 lb -centesimalminute 1e-2 grade -centesimalsecond 1e-4 grade -century 100 year -cfs ft3/sec -chain 66 ft -circularinch 1|4 pi-in2 -circularmil 1e-6|4 pi-in2 -clusec 1e-8 mm-hg m3/s -coomb 4 bu -cord 128 ft3 -cordfoot cord -crith 9.06e-2 gm -cubit 18 in -cup 1|2 pt -curie 3.7e+10 /sec -dalton amu -decade 10 yr -dipotre /m -displacementton 35 ft3 -doppelzentner 100 kg -dozen 12 -drop .03 cm3 -dyne cm-gm/sec2 -electronvolt e-volt -ell 45 in -engineerschain 100 ft -engineerslink 100|100 ft -equivalentfootcandle lumen/pi-ft2 -equivalentlux lumen/pi-m2 -equivalentphot cd/pi-cm2 -erg cm2-gm/sec2 -ev e-volt -faraday 9.652e+4 coul -fathom 6 ft -fermi 1e-15 m -fifth 4|5 qt -fin 5 dollar -finger 7|8 in -firkin 9 gal -footcandle lumen/ft2 -footlambert cd/pi-ft2 -fortnight 14 da -franklin 3.33564e-10 coul -frigorie kilocal -furlong 220 yd -galileo 1e-2 m/sec2 -gamma 1e-9 weber/m2 -gauss 1e-4 weber/m2 -geodeticfoot british-ft -geographicalmile 1852 m -gilbert 7.95775e-1 amp -gill 1|4 pt -gross 144 -gunterschain 22 yd -hand 4 in -hectare 1e+4 m2 -hefnercandle .92 cd -hertz /sec -Hz hertz -hogshead 2 barrel -hd hogshead -homestead 1|4 mi2 -horsepower 550 ft-lb-g/sec -hp horsepower -hyl gm force sec2/m -hz /sec -imaginarycubicfoot 1.4 ft3 -jeroboam 4|5 gal -karat 1|24 -kcal kilocal -kcalorie kilocal -kev 1e+3 e-volt -key kg -khz 1e+3 /sec -kilderkin 18 gal -knot nmile/hr -lambert cd/pi-cm2 -langley cal/cm2 -last 80 bu -league 3 mi -lightyear c-yr -line 1|12 in -link 66|100 ft -longhundredweight 112 lb -longquarter 28 lb -lusec 1e-6 mm-hg m3/s -mach 331.46 m/sec -magnum 2 qt -marineleague 3 nmile -maxwell 1e-8 weber -metriccarat 200 mg -mgd megagal/day -mh millihenry -mhz 1e+6 /sec -mil 1e-3 in -millenium 1000 year -minersinch 1.5 ft3/min -minim 1|60 fldr -mo month -mpg mile/gal -mph mile/hr -nail 1|16 yd -nauticalmile nmile -nit cd/m2 -noggin 1|8 qt -nox 1e-3 lux -ns nanosec -oersted 2.5e+2 pi-amp/m -oe oersted -pace 36 in -palm 3 in -parasang 3.5 mi -parsec au-radian/arcsec -pascal nt/m2 -pc parsec -pennyweight 1|20 oz -pwt pennyweight -percent % -perch rd -pf picofarad -phot lumen/cm2 -pica 1|6 in -pieze 1e+3 nt/m2 -pipe 4 barrel -point 1|72 in -poise gm/cm-sec -pole rd -poundal ft-lb/sec2 -pdl poundal -proof 1|200 -psi lb-g/in2 -quarter 9 in -quartersection 1|4 mi2 -quintal 100 kg -quire 25 -rad 100 erg/gm -ream 500 -registerton 100 ft3 -rehoboam 156 floz -rhe 10 m2/nt-sec -rontgen 2.58e-4 curie/kg -rood 1.21e+3 yd -rope 20 ft -rutherford 1e+6 /sec -rydberg 1.36054e+1 ev -sabin 1 ft2 -sack 3 bu -seam 8 bu -section mi2 -shippington 40 ft3 -shorthundredweight 100 lb -shortquarter 25 lb -siemens /ohm -sigma microsec -skein 120 yd -skot 1e-3 apostilb -slug lb-g-sec2/ft -span 9 in -spat 4 pi sr -spindle 14400 yd -square 100 ft2 -stere m3 -sthene 1e+3 nt -stilb cd/cm2 -stoke 1e-4 m2/sec -stone 14 lb -strike 2 bu -surveyfoot british-ft -surveyyard 3 surveyfoot -surveyorschain 66 ft -surveyorslink 66|100 ft -tablespoon 4 fldr -teaspoon 4|3 fldr -tesla weber/m2 -therm 1e+5 btu -thermie 1e+6 cal -timberfoot ft3 -tnt 4.6e+6 m2/sec2 -tonne 1e+6 gm -torr mm hg -township 36 mi2 -tun 8 barrel -water gram g / cc -wey 40 bu -weymass 252 lb -Xunit 1.00202e-13 m -k 1.38047e-16 erg/degC - - -degC K -kelvin K -brewster 1e-12 m2/newton -degF 5|9 degC -degreesrankine degF -degrankine degreesrankine -degreerankine degF -degreaumur 10|8 degC -drachm 60 grain -poncelet 100 kg m g / sec -denier .05|450 gram / m -tex .001 gram / m -englishell 45 inch -scottishell 37.2 inch -flemishell 27 inch -planck 6.626e-34 joule-sec -hbar 1.055e-34 joule-sec -electronmass 9.1095e-31 kg -protonmass 1.6726e-27 kg -neutronmass 1.6606e-27 kg -V volt -eV e V -bohrradius hbar2-C2/8.988e9 N m2-e2-electronmass -becquerel 1|3.7e10 curie -fresnel 1e12 hertz -statcoul 1|2.99792458e9 coul -statamp 1|2.99792458e9 amp -statvolt 2.99792458e2 volt -statcoulomb statcoul -statampere statamp -debye 3.336e-30 coul-m -pulsatance 2 pi/sec -rpm rev/minute -rps rev/sec -kilohm kiloohm -megohm megaohm -siderealyear 365.256360417 day -siderealday 23.934469444 hour -siderealhour 1|24 sidereal day -lunarmonth 29.5305555 day -synodicmonth lunarmonth -siderealmonth 27.32152777 day -tropicalyear year -solaryear year -lunaryear 12 lunarmonth -cran 37.5 brgallon -kip 1000 lbf -frenchfoot 16|15 ft -frenchfeet frenchfoot -toise 6 frenchfeet -sievert 8.4 rontgen -candle 1.02 candela -militarypace 2.5 feet -metre meter -litre liter -gramme gram -iudiptheria 62.8 microgram -iupenicillin .6 microgram -iuinsulin 41.67 microgram -cottonyarncount 2520 ft/pound -linenyarncount 900 ft/pound -worstedyarncount 1680 ft/pound -metricyarncount meter/gram -jewlerspoint 2 milligram - diff --git a/usr.bin/whereis/whereis.1 b/usr.bin/whereis/whereis.1 deleted file mode 100644 index 7304934962d1..000000000000 --- a/usr.bin/whereis/whereis.1 +++ /dev/null @@ -1,75 +0,0 @@ -.\" $NetBSD: whereis.1,v 1.12 2001/12/01 16:43:27 wiz Exp $ -.\" -.\" Copyright (c) 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)whereis.1 8.3 (Berkeley) 4/27/95 -.\" -.Dd April 27, 1995 -.Dt WHEREIS 1 -.Os -.Sh NAME -.Nm whereis -.Nd locate programs -.Sh SYNOPSIS -.Nm -.Op Fl p -.Ar program -.Op Ar program ... -.Sh DESCRIPTION -The -.Nm -utility checks the standard binary directories for the specified programs, -printing out the paths of any it finds. -.Pp -The default path searched is the string returned by the -.Xr sysctl 8 -utility for the -.Dq user.cs_path -string. -If the -.Op Fl p -option is specified, then the value of the environment -variable -.Ev PATH -is used instead. -.Sh SEE ALSO -.Xr which 1 , -.Xr sysctl 8 -.Sh COMPATIBILITY -The historic flags and arguments for the -.Nm -utility are no longer available in this version. -.Sh HISTORY -The -.Nm -command appeared in -.Bx 3.0 . diff --git a/usr.bin/whereis/whereis.c b/usr.bin/whereis/whereis.c deleted file mode 100644 index c7801366f2a7..000000000000 --- a/usr.bin/whereis/whereis.c +++ /dev/null @@ -1,138 +0,0 @@ -/* $NetBSD: whereis.c,v 1.11 2002/06/11 06:06:21 itojun Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1993\n\ - The Regents of the University of California. All rights reserved.\n"); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)whereis.c 8.3 (Berkeley) 5/4/95"; -#endif -__RCSID("$NetBSD: whereis.c,v 1.11 2002/06/11 06:06:21 itojun Exp $"); -#endif /* not lint */ - -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/sysctl.h> - -#include <err.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -void usage __P((void)); -int main __P((int, char *[])); - -int -main(argc, argv) - int argc; - char *argv[]; -{ - struct stat sb; - size_t len; - int ch, sverrno, mib[2]; - char *p, *t, *std, path[MAXPATHLEN]; - int useenvpath = 0; - - while ((ch = getopt(argc, argv, "p")) != -1) - switch (ch) { - case 'p': - useenvpath = 1; /* use environment for PATH */ - break; - - case '?': - default: - usage(); - } - argc -= optind; - argv += optind; - - if (argc == 0) - usage(); - - if (useenvpath) { - if ((std = getenv("PATH")) == NULL) - err(1, "getenv: PATH" ); - } else { - /* Retrieve the standard path. */ - mib[0] = CTL_USER; - mib[1] = USER_CS_PATH; - if (sysctl(mib, 2, NULL, &len, NULL, 0) == -1) - return (-1); - if (len == 0) - err(1, "user_cs_path: sysctl: zero length"); - if ((std = malloc(len)) == NULL) - err(1, NULL); - if (sysctl(mib, 2, std, &len, NULL, 0) == -1) { - sverrno = errno; - free(std); - errno = sverrno; - err(1, "sysctl: user_cs_path"); - } - } - - /* For each path, for each program... */ - for (; *argv; ++argv) - for (p = std;; *p++ = ':') { - t = p; - if ((p = strchr(p, ':')) != NULL) { - *p = '\0'; - if (t == p) - t = "."; - } else - if (strlen(t) == 0) - t = "."; - (void)snprintf(path, sizeof(path), "%s/%s", t, *argv); - if (!stat(path, &sb)) - (void)printf("%s\n", path); - if (p == NULL) - break; - } - - return (0); -} - -void -usage() -{ - - (void)fprintf(stderr, "usage: whereis [-p] program [...]\n"); - exit (1); -} |
