diff options
Diffstat (limited to 'winsup/cygwin/libc')
-rw-r--r-- | winsup/cygwin/libc/bsdlib.cc | 312 | ||||
-rw-r--r-- | winsup/cygwin/libc/fnmatch.c | 220 | ||||
-rw-r--r-- | winsup/cygwin/libc/fts.c | 1253 | ||||
-rw-r--r-- | winsup/cygwin/libc/ftw.c | 102 | ||||
-rw-r--r-- | winsup/cygwin/libc/getopt.c | 548 | ||||
-rw-r--r-- | winsup/cygwin/libc/inet_addr.c | 228 | ||||
-rw-r--r-- | winsup/cygwin/libc/inet_network.c | 124 | ||||
-rw-r--r-- | winsup/cygwin/libc/memmem.cc | 67 | ||||
-rw-r--r-- | winsup/cygwin/libc/nftw.c | 121 | ||||
-rw-r--r-- | winsup/cygwin/libc/rcmd.cc | 782 | ||||
-rw-r--r-- | winsup/cygwin/libc/rexec.cc | 415 | ||||
-rw-r--r-- | winsup/cygwin/libc/strptime.cc | 545 | ||||
-rw-r--r-- | winsup/cygwin/libc/timelocal.cc | 125 | ||||
-rw-r--r-- | winsup/cygwin/libc/timelocal.h | 65 |
14 files changed, 0 insertions, 4907 deletions
diff --git a/winsup/cygwin/libc/bsdlib.cc b/winsup/cygwin/libc/bsdlib.cc deleted file mode 100644 index 48ccc4578..000000000 --- a/winsup/cygwin/libc/bsdlib.cc +++ /dev/null @@ -1,312 +0,0 @@ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * CV 2003-09-10: Cygwin specific changes applied. Code simplified just - * for Cygwin alone. - */ - -#include "winsup.h" -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <utmp.h> -#include <unistd.h> -#include <sys/termios.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include "cygerrno.h" -#include "thread.h" -#include "cygtls.h" - -extern "C" int -daemon (int nochdir, int noclose) -{ - int fd; - - switch (fork ()) - { - case -1: - return -1; - case 0: - if (!wincap.is_winnt ()) - { - /* Register as service under 9x/Me which allows to close - the parent window with the daemon still running. - This function only exists on 9x/Me and is autoloaded - so it fails silently on NT. */ - DWORD WINAPI RegisterServiceProcess (DWORD, DWORD); - RegisterServiceProcess (0, 1); - } - break; - default: - /* This sleep avoids a race condition which kills the - child process if parent is started by a NT/W2K service. - FIXME: Is that still true? */ - Sleep (1000L); - _exit (0); - } - if (setsid () == -1) - return -1; - if (!nochdir) - chdir ("/"); - if (!noclose && (fd = open (_PATH_DEVNULL, O_RDWR, 0)) >= 0) - { - dup2 (fd, STDIN_FILENO); - dup2 (fd, STDOUT_FILENO); - dup2 (fd, STDERR_FILENO); - if (fd > 2) - close (fd); - } - return 0; -} - -extern "C" int -login_tty (int fd) -{ - char *fdname; - int newfd; - - if (setsid () == -1) - return -1; - if ((fdname = ttyname (fd))) - { - if (fd != STDIN_FILENO) - close (STDIN_FILENO); - if (fd != STDOUT_FILENO) - close (STDOUT_FILENO); - if (fd != STDERR_FILENO) - close (STDERR_FILENO); - newfd = open (fdname, O_RDWR); - close (newfd); - } - dup2 (fd, STDIN_FILENO); - dup2 (fd, STDOUT_FILENO); - dup2 (fd, STDERR_FILENO); - if (fd > 2) - close (fd); - return 0; -} - -extern "C" int -openpty (int *amaster, int *aslave, char *name, struct termios *termp, - struct winsize *winp) -{ - int master, slave; - char pts[CYG_MAX_PATH]; - - if ((master = open ("/dev/ptmx", O_RDWR | O_NOCTTY)) >= 0) - { - grantpt (master); - unlockpt (master); - strcpy (pts, ptsname (master)); - revoke (pts); - if ((slave = open (pts, O_RDWR | O_NOCTTY)) >= 0) - { - if (amaster) - *amaster = master; - if (aslave) - *aslave = slave; - if (name) - strcpy (name, pts); - if (termp) - tcsetattr (slave, TCSAFLUSH, termp); - if (winp) - ioctl (slave, TIOCSWINSZ, (char *) winp); - return 0; - } - close (master); - } - set_errno (ENOENT); - return -1; -} - -extern "C" int -forkpty (int *amaster, char *name, struct termios *termp, struct winsize *winp) -{ - int master, slave, pid; - - if (openpty (&master, &slave, name, termp, winp) == -1) - return -1; - switch (pid = fork ()) - { - case -1: - return -1; - case 0: - close (master); - login_tty (slave); - return 0; - } - if (amaster) - *amaster = master; - close (slave); - return pid; -} - -extern "C" char *__progname; - -static void -_vwarnx (const char *fmt, va_list ap) -{ - fprintf (stderr, "%s: ", __progname); - vfprintf (stderr, fmt, ap); -} - -extern "C" void -vwarn (const char *fmt, va_list ap) -{ - _vwarnx (fmt, ap); - fprintf (stderr, ": %s", strerror (get_errno ())); - fputc ('\n', stderr); -} - -extern "C" void -vwarnx (const char *fmt, va_list ap) -{ - _vwarnx (fmt, ap); - fputc ('\n', stderr); -} - -extern "C" void -warn (const char *fmt, ...) -{ - va_list ap; - va_start (ap, fmt); - vwarn (fmt, ap); -} - -extern "C" void -warnx (const char *fmt, ...) -{ - va_list ap; - va_start (ap, fmt); - vwarnx (fmt, ap); -} - -extern "C" void -verr (int eval, const char *fmt, va_list ap) -{ - vwarn (fmt, ap); - exit (eval); -} - -extern "C" void -verrx (int eval, const char *fmt, va_list ap) -{ - vwarnx (fmt, ap); - exit (eval); -} - -extern "C" void -err (int eval, const char *fmt, ...) -{ - va_list ap; - va_start (ap, fmt); - vwarn (fmt, ap); - exit (eval); -} - -extern "C" void -errx (int eval, const char *fmt, ...) -{ - va_list ap; - va_start (ap, fmt); - vwarnx (fmt, ap); - exit (eval); -} - -extern "C" const char * -getprogname (void) -{ - return __progname; -} - -extern "C" void -setprogname (const char *newprogname) -{ - myfault efault; - if (!efault.faulted (EFAULT)) - { - /* Per BSD man page, setprogname keeps a pointer to the last - path component of the argument. It does *not* copy the - argument before. */ - __progname = strrchr (newprogname, '/'); - if (__progname) - ++__progname; - else - __progname = (char *)newprogname; - } -} - -extern "C" void -logwtmp (const char *line, const char *user, const char *host) -{ - struct utmp ut; - memset (&ut, 0, sizeof ut); - ut.ut_type = USER_PROCESS; - ut.ut_pid = getpid (); - if (line) - strncpy (ut.ut_line, line, sizeof ut.ut_line); - time (&ut.ut_time); - if (user) - strncpy (ut.ut_user, user, sizeof ut.ut_user); - if (host) - strncpy (ut.ut_host, host, sizeof ut.ut_host); - updwtmp (_PATH_WTMP, &ut); -} - -extern "C" void -login (struct utmp *ut) -{ - pututline (ut); - endutent (); - updwtmp (_PATH_WTMP, ut); -} - -extern "C" int -logout (char *line) -{ - struct utmp ut_buf, *ut; - - memset (&ut_buf, 0, sizeof ut_buf); - strncpy (ut_buf.ut_line, line, sizeof ut_buf.ut_line); - setutent (); - ut = getutline (&ut_buf); - - if (ut) - { - ut->ut_type = DEAD_PROCESS; - memset (ut->ut_user, 0, sizeof ut->ut_user); - memset (ut->ut_host, 0, sizeof ut->ut_host); - time (&ut->ut_time); - debug_printf ("set logout time for %s", line); - pututline (ut); - endutent (); - return 1; - } - return 0; -} diff --git a/winsup/cygwin/libc/fnmatch.c b/winsup/cygwin/libc/fnmatch.c deleted file mode 100644 index b48d9e00a..000000000 --- a/winsup/cygwin/libc/fnmatch.c +++ /dev/null @@ -1,220 +0,0 @@ -/* $OpenBSD: fnmatch.c,v 1.7 2000/03/23 19:13:51 millert Exp $ */ - -/* - * Copyright (c) 1989, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Guido van Rossum. - * - * 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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94"; -#else -static char rcsid[] = "$OpenBSD: fnmatch.c,v 1.7 2000/03/23 19:13:51 millert Exp $"; -#endif -#endif /* LIBC_SCCS and not lint */ - -/* - * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. - * Compares a filename or pathname to a pattern. - */ - -/* Just this single line added for Cygwin. */ -#include "winsup.h" - -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include <fnmatch.h> - -#define EOS '\0' - -#define RANGE_MATCH 1 -#define RANGE_NOMATCH 0 -#define RANGE_ERROR (-1) - -static int rangematch __P((const char *, char, int, char **)); - -int -fnmatch(const char *pattern, const char *string, int flags) -{ - const char *stringstart; - char *newp; - char c, test; - - for (stringstart = string;;) - switch (c = *pattern++) { - case EOS: - if ((flags & FNM_LEADING_DIR) && *string == '/') - return (0); - return (*string == EOS ? 0 : FNM_NOMATCH); - case '?': - if (*string == EOS) - return (FNM_NOMATCH); - if (*string == '/' && (flags & FNM_PATHNAME)) - return (FNM_NOMATCH); - if (*string == '.' && (flags & FNM_PERIOD) && - (string == stringstart || - ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) - return (FNM_NOMATCH); - ++string; - break; - case '*': - c = *pattern; - /* Collapse multiple stars. */ - while (c == '*') - c = *++pattern; - - if (*string == '.' && (flags & FNM_PERIOD) && - (string == stringstart || - ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) - return (FNM_NOMATCH); - - /* Optimize for pattern with * at end or before /. */ - if (c == EOS) { - if (flags & FNM_PATHNAME) - return ((flags & FNM_LEADING_DIR) || - strchr(string, '/') == NULL ? - 0 : FNM_NOMATCH); - else - return (0); - } else if (c == '/' && (flags & FNM_PATHNAME)) { - if ((string = strchr(string, '/')) == NULL) - return (FNM_NOMATCH); - break; - } - - /* General case, use recursion. */ - while ((test = *string) != EOS) { - if (!fnmatch(pattern, string, flags & ~FNM_PERIOD)) - return (0); - if (test == '/' && (flags & FNM_PATHNAME)) - break; - ++string; - } - return (FNM_NOMATCH); - case '[': - if (*string == EOS) - return (FNM_NOMATCH); - if (*string == '/' && (flags & FNM_PATHNAME)) - return (FNM_NOMATCH); - if (*string == '.' && (flags & FNM_PERIOD) && - (string == stringstart || - ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) - return (FNM_NOMATCH); - - switch (rangematch(pattern, *string, flags, &newp)) { - case RANGE_ERROR: - /* not a good range, treat as normal text */ - goto normal; - case RANGE_MATCH: - pattern = newp; - break; - case RANGE_NOMATCH: - return (FNM_NOMATCH); - } - ++string; - break; - case '\\': - if (!(flags & FNM_NOESCAPE)) { - if ((c = *pattern++) == EOS) { - c = '\\'; - --pattern; - } - } - /* FALLTHROUGH */ - default: - normal: - if (c != *string && !((flags & FNM_CASEFOLD) && - (tolower((unsigned char)c) == - tolower((unsigned char)*string)))) - return (FNM_NOMATCH); - ++string; - break; - } - /* NOTREACHED */ -} - -static int -rangematch(const char *pattern, char test, int flags, char **newp) -{ - int negate, ok; - char c, c2; - - /* - * A bracket expression starting with an unquoted circumflex - * character produces unspecified results (IEEE 1003.2-1992, - * 3.13.2). This implementation treats it like '!', for - * consistency with the regular expression syntax. - * J.T. Conklin (conklin@ngai.kaleida.com) - */ - if ((negate = (*pattern == '!' || *pattern == '^'))) - ++pattern; - - if (flags & FNM_CASEFOLD) - test = tolower((unsigned char)test); - - /* - * A right bracket shall lose its special meaning and represent - * itself in a bracket expression if it occurs first in the list. - * -- POSIX.2 2.8.3.2 - */ - ok = 0; - c = *pattern++; - do { - if (c == '\\' && !(flags & FNM_NOESCAPE)) - c = *pattern++; - if (c == EOS) - return (RANGE_ERROR); - if (c == '/' && (flags & FNM_PATHNAME)) - return (RANGE_NOMATCH); - if ((flags & FNM_CASEFOLD)) - c = tolower((unsigned char)c); - if (*pattern == '-' - && (c2 = *(pattern+1)) != EOS && c2 != ']') { - pattern += 2; - if (c2 == '\\' && !(flags & FNM_NOESCAPE)) - c2 = *pattern++; - if (c2 == EOS) - return (RANGE_ERROR); - if (flags & FNM_CASEFOLD) - c2 = tolower((unsigned char)c2); - if (c <= test && test <= c2) - ok = 1; - } else if (c == test) - ok = 1; - } while ((c = *pattern++) != ']'); - - *newp = (char *)pattern; - return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH); -} diff --git a/winsup/cygwin/libc/fts.c b/winsup/cygwin/libc/fts.c deleted file mode 100644 index d0e77892d..000000000 --- a/winsup/cygwin/libc/fts.c +++ /dev/null @@ -1,1253 +0,0 @@ -/*- - * Copyright (c) 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - * - * $OpenBSD: fts.c,v 1.22 1999/10/03 19:22:22 millert Exp $ - */ - -#if 0 -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94"; -#endif /* LIBC_SCCS and not lint */ -#endif -#ifdef __CYGWIN__ -#include "winsup.h" -#include <sys/statfs.h> -#define __FBSDID(x) -#define _open open -#define _close close -#define reallocf realloc -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/gen/fts.c,v 1.27 2004/06/08 06:23:23 das Exp $"); - -#ifndef __CYGWIN__ -#include "namespace.h" -#endif -#include <sys/param.h> -#include <sys/mount.h> -#include <sys/stat.h> - -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <fts.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#ifndef __CYGWIN__ -#include "un-namespace.h" -#endif - -static FTSENT *fts_alloc(FTS *, const char *, int); -static FTSENT *fts_build(FTS *, int); -static void fts_lfree(FTSENT *); -static void fts_load(FTS *, FTSENT *); -static size_t fts_maxarglen(char * const *); -static void fts_padjust(FTS *, FTSENT *); -static int fts_palloc(FTS *, size_t); -static FTSENT *fts_sort(FTS *, FTSENT *, int); -static u_short fts_stat(FTS *, FTSENT *, int); -static int fts_safe_changedir(FTS *, FTSENT *, int, const char *); -static int fts_ufslinks(FTS *, const FTSENT *); - -#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) - -#define CLR(opt) (sp->fts_options &= ~(opt)) -#define ISSET(opt) (sp->fts_options & (opt)) -#define SET(opt) (sp->fts_options |= (opt)) - -#define FCHDIR(sp, fd) (!ISSET(FTS_NOCHDIR) && fchdir(fd)) - -/* fts_build flags */ -#define BCHILD 1 /* fts_children */ -#define BNAMES 2 /* fts_children, names only */ -#define BREAD 3 /* fts_read */ - -/* - * Internal representation of an FTS, including extra implementation - * details. The FTS returned from fts_open points to this structure's - * ftsp_fts member (and can be cast to an _fts_private as required) - */ -struct _fts_private { - FTS ftsp_fts; - struct statfs ftsp_statfs; - __dev32_t ftsp_dev; - int ftsp_linksreliable; -}; - -/* - * The "FTS_NOSTAT" option can avoid a lot of calls to stat(2) if it - * knows that a directory could not possibly have subdirectories. This - * is decided by looking at the link count: a subdirectory would - * increment its parent's link count by virtue of its own ".." entry. - * This assumption only holds for UFS-like filesystems that implement - * links and directories this way, so we must punt for others. - */ - -#ifndef __CYGWIN__ -static const char *ufslike_filesystems[] = { - "ufs", - "nfs", - "nfs4", - "ext2fs", - 0 -}; -#endif - -FTS * -fts_open(argv, options, compar) - char * const *argv; - int options; - int (*compar)(const FTSENT * const *, const FTSENT * const *); -{ - struct _fts_private *priv; - FTS *sp; - FTSENT *p, *root; - int nitems; - FTSENT *parent, *tmp; - int len; - - /* Options check. */ - if (options & ~FTS_OPTIONMASK) { - errno = EINVAL; - return (NULL); - } - - /* Allocate/initialize the stream. */ - if ((priv = malloc(sizeof(*priv))) == NULL) - return (NULL); - memset(priv, 0, sizeof(*priv)); - sp = &priv->ftsp_fts; - sp->fts_compar = compar; - sp->fts_options = options; - - /* Shush, GCC. */ - tmp = NULL; - - /* Logical walks turn on NOCHDIR; symbolic links are too hard. */ - if (ISSET(FTS_LOGICAL)) - SET(FTS_NOCHDIR); - - /* - * Start out with 1K of path space, and enough, in any case, - * to hold the user's paths. - */ - if (fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN))) - goto mem1; - - /* Allocate/initialize root's parent. */ - if ((parent = fts_alloc(sp, "", 0)) == NULL) - goto mem2; - parent->fts_level = FTS_ROOTPARENTLEVEL; - - /* Allocate/initialize root(s). */ - for (root = NULL, nitems = 0; *argv != NULL; ++argv, ++nitems) { - /* Don't allow zero-length paths. */ - if ((len = strlen(*argv)) == 0) { - errno = ENOENT; - goto mem3; - } - - p = fts_alloc(sp, *argv, len); - p->fts_level = FTS_ROOTLEVEL; - p->fts_parent = parent; - p->fts_accpath = p->fts_name; - p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW)); - - /* Command-line "." and ".." are real directories. */ - if (p->fts_info == FTS_DOT) - p->fts_info = FTS_D; - - /* - * If comparison routine supplied, traverse in sorted - * order; otherwise traverse in the order specified. - */ - if (compar) { - p->fts_link = root; - root = p; - } else { - p->fts_link = NULL; - if (root == NULL) - tmp = root = p; - else { - tmp->fts_link = p; - tmp = p; - } - } - } - if (compar && nitems > 1) - root = fts_sort(sp, root, nitems); - - /* - * Allocate a dummy pointer and make fts_read think that we've just - * finished the node before the root(s); set p->fts_info to FTS_INIT - * so that everything about the "current" node is ignored. - */ - if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL) - goto mem3; - sp->fts_cur->fts_link = root; - sp->fts_cur->fts_info = FTS_INIT; - - /* - * If using chdir(2), grab a file descriptor pointing to dot to ensure - * that we can get back here; this could be avoided for some paths, - * but almost certainly not worth the effort. Slashes, symbolic links, - * and ".." are all fairly nasty problems. Note, if we can't get the - * descriptor we run anyway, just more slowly. - */ - if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = _open(".", O_RDONLY, 0)) < 0) - SET(FTS_NOCHDIR); - - return (sp); - -mem3: fts_lfree(root); - free(parent); -mem2: free(sp->fts_path); -mem1: free(sp); - return (NULL); -} - -static void -fts_load(sp, p) - FTS *sp; - FTSENT *p; -{ - int len; - char *cp; - - /* - * Load the stream structure for the next traversal. Since we don't - * actually enter the directory until after the preorder visit, set - * the fts_accpath field specially so the chdir gets done to the right - * place and the user can access the first node. From fts_open it's - * known that the path will fit. - */ - len = p->fts_pathlen = p->fts_namelen; - memmove(sp->fts_path, p->fts_name, len + 1); - if ((cp = strrchr(p->fts_name, '/')) && (cp != p->fts_name || cp[1])) { - len = strlen(++cp); - memmove(p->fts_name, cp, len + 1); - p->fts_namelen = len; - } - p->fts_accpath = p->fts_path = sp->fts_path; - sp->fts_dev = p->fts_dev; -} - -int -fts_close(sp) - FTS *sp; -{ - FTSENT *freep, *p; - int saved_errno; - - /* - * This still works if we haven't read anything -- the dummy structure - * points to the root list, so we step through to the end of the root - * list which has a valid parent pointer. - */ - if (sp->fts_cur) { - for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) { - freep = p; - p = p->fts_link != NULL ? p->fts_link : p->fts_parent; - free(freep); - } - free(p); - } - - /* Free up child linked list, sort array, path buffer. */ - if (sp->fts_child) - fts_lfree(sp->fts_child); - if (sp->fts_array) - free(sp->fts_array); - free(sp->fts_path); - - /* Return to original directory, save errno if necessary. */ - if (!ISSET(FTS_NOCHDIR)) { - saved_errno = fchdir(sp->fts_rfd) ? errno : 0; - (void)_close(sp->fts_rfd); - - /* Set errno and return. */ - if (saved_errno != 0) { - /* Free up the stream pointer. */ - free(sp); - errno = saved_errno; - return (-1); - } - } - - /* Free up the stream pointer. */ - free(sp); - return (0); -} - -/* - * Special case of "/" at the end of the path so that slashes aren't - * appended which would cause paths to be written as "....//foo". - */ -#define NAPPEND(p) \ - (p->fts_path[p->fts_pathlen - 1] == '/' \ - ? p->fts_pathlen - 1 : p->fts_pathlen) - -FTSENT * -fts_read(sp) - FTS *sp; -{ - FTSENT *p, *tmp; - int instr; - char *t; - int saved_errno; - - /* If finished or unrecoverable error, return NULL. */ - if (sp->fts_cur == NULL || ISSET(FTS_STOP)) - return (NULL); - - /* Set current node pointer. */ - p = sp->fts_cur; - - /* Save and zero out user instructions. */ - instr = p->fts_instr; - p->fts_instr = FTS_NOINSTR; - - /* Any type of file may be re-visited; re-stat and re-turn. */ - if (instr == FTS_AGAIN) { - p->fts_info = fts_stat(sp, p, 0); - return (p); - } - - /* - * Following a symlink -- SLNONE test allows application to see - * SLNONE and recover. If indirecting through a symlink, have - * keep a pointer to current location. If unable to get that - * pointer, follow fails. - */ - if (instr == FTS_FOLLOW && - (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) { - p->fts_info = fts_stat(sp, p, 1); - if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { - if ((p->fts_symfd = _open(".", O_RDONLY, 0)) < 0) { - p->fts_errno = errno; - p->fts_info = FTS_ERR; - } else - p->fts_flags |= FTS_SYMFOLLOW; - } - return (p); - } - - /* Directory in pre-order. */ - if (p->fts_info == FTS_D) { - /* If skipped or crossed mount point, do post-order visit. */ - if (instr == FTS_SKIP || - (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) { - if (p->fts_flags & FTS_SYMFOLLOW) - (void)_close(p->fts_symfd); - if (sp->fts_child) { - fts_lfree(sp->fts_child); - sp->fts_child = NULL; - } - p->fts_info = FTS_DP; - return (p); - } - - /* Rebuild if only read the names and now traversing. */ - if (sp->fts_child != NULL && ISSET(FTS_NAMEONLY)) { - CLR(FTS_NAMEONLY); - fts_lfree(sp->fts_child); - sp->fts_child = NULL; - } - - /* - * Cd to the subdirectory. - * - * If have already read and now fail to chdir, whack the list - * to make the names come out right, and set the parent errno - * so the application will eventually get an error condition. - * Set the FTS_DONTCHDIR flag so that when we logically change - * directories back to the parent we don't do a chdir. - * - * If haven't read do so. If the read fails, fts_build sets - * FTS_STOP or the fts_info field of the node. - */ - if (sp->fts_child != NULL) { - if (fts_safe_changedir(sp, p, -1, p->fts_accpath)) { - p->fts_errno = errno; - p->fts_flags |= FTS_DONTCHDIR; - for (p = sp->fts_child; p != NULL; - p = p->fts_link) - p->fts_accpath = - p->fts_parent->fts_accpath; - } - } else if ((sp->fts_child = fts_build(sp, BREAD)) == NULL) { - if (ISSET(FTS_STOP)) - return (NULL); - return (p); - } - p = sp->fts_child; - sp->fts_child = NULL; - goto name; - } - - /* Move to the next node on this level. */ -next: tmp = p; - if ((p = p->fts_link) != NULL) { - free(tmp); - - /* - * If reached the top, return to the original directory (or - * the root of the tree), and load the paths for the next root. - */ - if (p->fts_level == FTS_ROOTLEVEL) { - if (FCHDIR(sp, sp->fts_rfd)) { - SET(FTS_STOP); - return (NULL); - } - fts_load(sp, p); - return (sp->fts_cur = p); - } - - /* - * User may have called fts_set on the node. If skipped, - * ignore. If followed, get a file descriptor so we can - * get back if necessary. - */ - if (p->fts_instr == FTS_SKIP) - goto next; - if (p->fts_instr == FTS_FOLLOW) { - p->fts_info = fts_stat(sp, p, 1); - if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { - if ((p->fts_symfd = - _open(".", O_RDONLY, 0)) < 0) { - p->fts_errno = errno; - p->fts_info = FTS_ERR; - } else - p->fts_flags |= FTS_SYMFOLLOW; - } - p->fts_instr = FTS_NOINSTR; - } - -name: t = sp->fts_path + NAPPEND(p->fts_parent); - *t++ = '/'; - memmove(t, p->fts_name, p->fts_namelen + 1); - return (sp->fts_cur = p); - } - - /* Move up to the parent node. */ - p = tmp->fts_parent; - free(tmp); - - if (p->fts_level == FTS_ROOTPARENTLEVEL) { - /* - * Done; free everything up and set errno to 0 so the user - * can distinguish between error and EOF. - */ - free(p); - errno = 0; - return (sp->fts_cur = NULL); - } - - /* NUL terminate the pathname. */ - sp->fts_path[p->fts_pathlen] = '\0'; - - /* - * Return to the parent directory. If at a root node or came through - * a symlink, go back through the file descriptor. Otherwise, cd up - * one directory. - */ - if (p->fts_level == FTS_ROOTLEVEL) { - if (FCHDIR(sp, sp->fts_rfd)) { - SET(FTS_STOP); - return (NULL); - } - } else if (p->fts_flags & FTS_SYMFOLLOW) { - if (FCHDIR(sp, p->fts_symfd)) { - saved_errno = errno; - (void)_close(p->fts_symfd); - errno = saved_errno; - SET(FTS_STOP); - return (NULL); - } - (void)_close(p->fts_symfd); - } else if (!(p->fts_flags & FTS_DONTCHDIR) && - fts_safe_changedir(sp, p->fts_parent, -1, "..")) { - SET(FTS_STOP); - return (NULL); - } - p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; - return (sp->fts_cur = p); -} - -/* - * Fts_set takes the stream as an argument although it's not used in this - * implementation; it would be necessary if anyone wanted to add global - * semantics to fts using fts_set. An error return is allowed for similar - * reasons. - */ -/* ARGSUSED */ -int -fts_set(sp, p, instr) - FTS *sp; - FTSENT *p; - int instr; -{ - if (instr != 0 && instr != FTS_AGAIN && instr != FTS_FOLLOW && - instr != FTS_NOINSTR && instr != FTS_SKIP) { - errno = EINVAL; - return (1); - } - p->fts_instr = instr; - return (0); -} - -FTSENT * -fts_children(sp, instr) - FTS *sp; - int instr; -{ - FTSENT *p; - int fd; - - if (instr != 0 && instr != FTS_NAMEONLY) { - errno = EINVAL; - return (NULL); - } - - /* Set current node pointer. */ - p = sp->fts_cur; - - /* - * Errno set to 0 so user can distinguish empty directory from - * an error. - */ - errno = 0; - - /* Fatal errors stop here. */ - if (ISSET(FTS_STOP)) - return (NULL); - - /* Return logical hierarchy of user's arguments. */ - if (p->fts_info == FTS_INIT) - return (p->fts_link); - - /* - * If not a directory being visited in pre-order, stop here. Could - * allow FTS_DNR, assuming the user has fixed the problem, but the - * same effect is available with FTS_AGAIN. - */ - if (p->fts_info != FTS_D /* && p->fts_info != FTS_DNR */) - return (NULL); - - /* Free up any previous child list. */ - if (sp->fts_child != NULL) - fts_lfree(sp->fts_child); - - if (instr == FTS_NAMEONLY) { - SET(FTS_NAMEONLY); - instr = BNAMES; - } else - instr = BCHILD; - - /* - * If using chdir on a relative path and called BEFORE fts_read does - * its chdir to the root of a traversal, we can lose -- we need to - * chdir into the subdirectory, and we don't know where the current - * directory is, so we can't get back so that the upcoming chdir by - * fts_read will work. - */ - if (p->fts_level != FTS_ROOTLEVEL || p->fts_accpath[0] == '/' || - ISSET(FTS_NOCHDIR)) - return (sp->fts_child = fts_build(sp, instr)); - - if ((fd = _open(".", O_RDONLY, 0)) < 0) - return (NULL); - sp->fts_child = fts_build(sp, instr); - if (fchdir(fd)) - return (NULL); - (void)_close(fd); - return (sp->fts_child); -} - -#ifndef fts_get_clientptr -#error "fts_get_clientptr not defined" -#endif - -void * -(fts_get_clientptr)(FTS *sp) -{ - - return (fts_get_clientptr(sp)); -} - -#ifndef fts_get_stream -#error "fts_get_stream not defined" -#endif - -FTS * -(fts_get_stream)(FTSENT *p) -{ - return (fts_get_stream(p)); -} - -void -fts_set_clientptr(FTS *sp, void *clientptr) -{ - - sp->fts_clientptr = clientptr; -} - -/* - * This is the tricky part -- do not casually change *anything* in here. The - * idea is to build the linked list of entries that are used by fts_children - * and fts_read. There are lots of special cases. - * - * The real slowdown in walking the tree is the stat calls. If FTS_NOSTAT is - * set and it's a physical walk (so that symbolic links can't be directories), - * we can do things quickly. First, if it's a 4.4BSD file system, the type - * of the file is in the directory entry. Otherwise, we assume that the number - * of subdirectories in a node is equal to the number of links to the parent. - * The former skips all stat calls. The latter skips stat calls in any leaf - * directories and for any files after the subdirectories in the directory have - * been found, cutting the stat calls by about 2/3. - */ -static FTSENT * -fts_build(sp, type) - FTS *sp; - int type; -{ - struct dirent *dp; - FTSENT *p, *head; - int nitems; - FTSENT *cur, *tail; - DIR *dirp; - void *oldaddr; - size_t dnamlen; - int cderrno, descend, len, level, maxlen, nlinks, /*oflag,*/ saved_errno, - nostat, doadjust; - char *cp; - - /* Set current node pointer. */ - cur = sp->fts_cur; - - /* - * Open the directory for reading. If this fails, we're done. - * If being called from fts_read, set the fts_info field. - */ -#ifdef FTS_WHITEOUT - if (ISSET(FTS_WHITEOUT)) - oflag = DTF_NODUP | DTF_REWIND; - else - oflag = DTF_HIDEW | DTF_NODUP | DTF_REWIND; -#else -#define __opendir2(path, flag) opendir(path) -#endif - if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) { - if (type == BREAD) { - cur->fts_info = FTS_DNR; - cur->fts_errno = errno; - } - return (NULL); - } - - /* - * Nlinks is the number of possible entries of type directory in the - * directory if we're cheating on stat calls, 0 if we're not doing - * any stat calls at all, -1 if we're doing stats on everything. - */ - if (type == BNAMES) { - nlinks = 0; - /* Be quiet about nostat, GCC. */ - nostat = 0; - } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) { - if (fts_ufslinks(sp, cur)) - nlinks = cur->fts_nlink - (ISSET(FTS_SEEDOT) ? 0 : 2); - else - nlinks = -1; - nostat = 1; - } else { - nlinks = -1; - nostat = 0; - } - -#ifdef notdef - (void)printf("nlinks == %d (cur: %d)\n", nlinks, cur->fts_nlink); - (void)printf("NOSTAT %d PHYSICAL %d SEEDOT %d\n", - ISSET(FTS_NOSTAT), ISSET(FTS_PHYSICAL), ISSET(FTS_SEEDOT)); -#endif - /* - * If we're going to need to stat anything or we want to descend - * and stay in the directory, chdir. If this fails we keep going, - * but set a flag so we don't chdir after the post-order visit. - * We won't be able to stat anything, but we can still return the - * names themselves. Note, that since fts_read won't be able to - * chdir into the directory, it will have to return different path - * names than before, i.e. "a/b" instead of "b". Since the node - * has already been visited in pre-order, have to wait until the - * post-order visit to return the error. There is a special case - * here, if there was nothing to stat then it's not an error to - * not be able to stat. This is all fairly nasty. If a program - * needed sorted entries or stat information, they had better be - * checking FTS_NS on the returned nodes. - */ - cderrno = 0; - if (nlinks || type == BREAD) { - if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) { - if (nlinks && type == BREAD) - cur->fts_errno = errno; - cur->fts_flags |= FTS_DONTCHDIR; - descend = 0; - cderrno = errno; - } else - descend = 1; - } else - descend = 0; - - /* - * Figure out the max file name length that can be stored in the - * current path -- the inner loop allocates more path as necessary. - * We really wouldn't have to do the maxlen calculations here, we - * could do them in fts_read before returning the path, but it's a - * lot easier here since the length is part of the dirent structure. - * - * If not changing directories set a pointer so that can just append - * each new name into the path. - */ - len = NAPPEND(cur); - if (ISSET(FTS_NOCHDIR)) { - cp = sp->fts_path + len; - *cp++ = '/'; - } else { - /* GCC, you're too verbose. */ - cp = NULL; - } - len++; - maxlen = sp->fts_pathlen - len; - - level = cur->fts_level + 1; - - /* Read the directory, attaching each entry to the `link' pointer. */ - doadjust = 0; - for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) { -#ifdef __CYGWIN__ - dnamlen = strlen (dp->d_name); -#else - dnamlen = dp->d_namlen; -#endif - if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name)) - continue; - - if ((p = fts_alloc(sp, dp->d_name, (int)dnamlen)) == NULL) - goto mem1; - if (dnamlen >= maxlen) { /* include space for NUL */ - oldaddr = sp->fts_path; - if (fts_palloc(sp, dnamlen + len + 1)) { - /* - * No more memory for path or structures. Save - * errno, free up the current structure and the - * structures already allocated. - */ -mem1: saved_errno = errno; - if (p) - free(p); - fts_lfree(head); - (void)closedir(dirp); - cur->fts_info = FTS_ERR; - SET(FTS_STOP); - errno = saved_errno; - return (NULL); - } - /* Did realloc() change the pointer? */ - if (oldaddr != sp->fts_path) { - doadjust = 1; - if (ISSET(FTS_NOCHDIR)) - cp = sp->fts_path + len; - } - maxlen = sp->fts_pathlen - len; - } - - if (len + dnamlen >= USHRT_MAX) { - /* - * In an FTSENT, fts_pathlen is a u_short so it is - * possible to wraparound here. If we do, free up - * the current structure and the structures already - * allocated, then error out with ENAMETOOLONG. - */ - free(p); - fts_lfree(head); - (void)closedir(dirp); - cur->fts_info = FTS_ERR; - SET(FTS_STOP); - errno = ENAMETOOLONG; - return (NULL); - } - p->fts_level = level; - p->fts_parent = sp->fts_cur; - p->fts_pathlen = len + dnamlen; - -#ifdef FTS_WHITEOUT - if (dp->d_type == DT_WHT) - p->fts_flags |= FTS_ISW; -#endif - - if (cderrno) { - if (nlinks) { - p->fts_info = FTS_NS; - p->fts_errno = cderrno; - } else - p->fts_info = FTS_NSOK; - p->fts_accpath = cur->fts_accpath; - } else if (nlinks == 0 -#if defined(DT_DIR) && !defined(__CYGWIN__) - || (nostat && - dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN) -#endif - ) { - p->fts_accpath = - ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name; - p->fts_info = FTS_NSOK; - } else { - /* Build a file name for fts_stat to stat. */ - if (ISSET(FTS_NOCHDIR)) { - p->fts_accpath = p->fts_path; - memmove(cp, p->fts_name, p->fts_namelen + 1); - } else - p->fts_accpath = p->fts_name; - /* Stat it. */ - p->fts_info = fts_stat(sp, p, 0); - - /* Decrement link count if applicable. */ - if (nlinks > 0 && (p->fts_info == FTS_D || - p->fts_info == FTS_DC || p->fts_info == FTS_DOT)) - --nlinks; - } - - /* We walk in directory order so "ls -f" doesn't get upset. */ - p->fts_link = NULL; - if (head == NULL) - head = tail = p; - else { - tail->fts_link = p; - tail = p; - } - ++nitems; - } - if (dirp) - (void)closedir(dirp); - - /* - * If realloc() changed the address of the path, adjust the - * addresses for the rest of the tree and the dir list. - */ - if (doadjust) - fts_padjust(sp, head); - - /* - * If not changing directories, reset the path back to original - * state. - */ - if (ISSET(FTS_NOCHDIR)) { - if (len == sp->fts_pathlen || nitems == 0) - --cp; - *cp = '\0'; - } - - /* - * If descended after called from fts_children or after called from - * fts_read and nothing found, get back. At the root level we use - * the saved fd; if one of fts_open()'s arguments is a relative path - * to an empty directory, we wind up here with no other way back. If - * can't get back, we're done. - */ - if (descend && (type == BCHILD || !nitems) && - (cur->fts_level == FTS_ROOTLEVEL ? - FCHDIR(sp, sp->fts_rfd) : - fts_safe_changedir(sp, cur->fts_parent, -1, ".."))) { - cur->fts_info = FTS_ERR; - SET(FTS_STOP); - return (NULL); - } - - /* If didn't find anything, return NULL. */ - if (!nitems) { - if (type == BREAD) - cur->fts_info = FTS_DP; - return (NULL); - } - - /* Sort the entries. */ - if (sp->fts_compar && nitems > 1) - head = fts_sort(sp, head, nitems); - return (head); -} - -static u_short -fts_stat(sp, p, follow) - FTS *sp; - FTSENT *p; - int follow; -{ - FTSENT *t; - __dev32_t dev; - __ino64_t ino; - struct __stat64 *sbp, sb; - int saved_errno; - - /* If user needs stat info, stat buffer already allocated. */ - sbp = ISSET(FTS_NOSTAT) ? &sb : p->fts_statp; - -#ifdef FTS_WHITEOUT - /* Check for whiteout. */ - if (p->fts_flags & FTS_ISW) { - if (sbp != &sb) { - memset(sbp, '\0', sizeof(*sbp)); - sbp->st_mode = S_IFWHT; - } - return (FTS_W); - } -#endif - - /* - * If doing a logical walk, or application requested FTS_FOLLOW, do - * a stat(2). If that fails, check for a non-existent symlink. If - * fail, set the errno from the stat call. - */ - if (ISSET(FTS_LOGICAL) || follow) { - if (stat64(p->fts_accpath, sbp)) { - saved_errno = errno; - if (!lstat64(p->fts_accpath, sbp)) { - errno = 0; - return (FTS_SLNONE); - } - p->fts_errno = saved_errno; - goto err; - } - } else if (lstat64(p->fts_accpath, sbp)) { - p->fts_errno = errno; -err: memset(sbp, 0, sizeof(struct __stat64)); - return (FTS_NS); - } - - if (S_ISDIR(sbp->st_mode)) { - /* - * Set the device/inode. Used to find cycles and check for - * crossing mount points. Also remember the link count, used - * in fts_build to limit the number of stat calls. It is - * understood that these fields are only referenced if fts_info - * is set to FTS_D. - */ - dev = p->fts_dev = sbp->st_dev; - ino = p->fts_ino = sbp->st_ino; - p->fts_nlink = sbp->st_nlink; - - if (ISDOT(p->fts_name)) - return (FTS_DOT); - - /* - * Cycle detection is done by brute force when the directory - * is first encountered. If the tree gets deep enough or the - * number of symbolic links to directories is high enough, - * something faster might be worthwhile. - */ - for (t = p->fts_parent; - t->fts_level >= FTS_ROOTLEVEL; t = t->fts_parent) - if (ino == t->fts_ino && dev == t->fts_dev) { - p->fts_cycle = t; - return (FTS_DC); - } - return (FTS_D); - } - if (S_ISLNK(sbp->st_mode)) - return (FTS_SL); - if (S_ISREG(sbp->st_mode)) - return (FTS_F); - return (FTS_DEFAULT); -} - -/* - * The comparison function takes pointers to pointers to FTSENT structures. - * Qsort wants a comparison function that takes pointers to void. - * (Both with appropriate levels of const-poisoning, of course!) - * Use a trampoline function to deal with the difference. - */ -static int -fts_compar(const void *a, const void *b) -{ - FTS *parent; - - parent = (*(const FTSENT * const *)a)->fts_fts; - return (*parent->fts_compar)(a, b); -} - -static FTSENT * -fts_sort(sp, head, nitems) - FTS *sp; - FTSENT *head; - int nitems; -{ - FTSENT **ap, *p; - - /* - * Construct an array of pointers to the structures and call qsort(3). - * Reassemble the array in the order returned by qsort. If unable to - * sort for memory reasons, return the directory entries in their - * current order. Allocate enough space for the current needs plus - * 40 so don't realloc one entry at a time. - */ - if (nitems > sp->fts_nitems) { - sp->fts_nitems = nitems + 40; - if ((sp->fts_array = reallocf(sp->fts_array, - sp->fts_nitems * sizeof(FTSENT *))) == NULL) { - sp->fts_nitems = 0; - return (head); - } - } - for (ap = sp->fts_array, p = head; p; p = p->fts_link) - *ap++ = p; - qsort(sp->fts_array, nitems, sizeof(FTSENT *), fts_compar); - for (head = *(ap = sp->fts_array); --nitems; ++ap) - ap[0]->fts_link = ap[1]; - ap[0]->fts_link = NULL; - return (head); -} - -static FTSENT * -fts_alloc(sp, name, namelen) - FTS *sp; - const char *name; - int namelen; -{ - FTSENT *p; - size_t len; - - struct ftsent_withstat { - FTSENT ent; - struct __stat64 statbuf; - }; - - /* - * The file name is a variable length array and no stat structure is - * necessary if the user has set the nostat bit. Allocate the FTSENT - * structure, the file name and the stat structure in one chunk, but - * be careful that the stat structure is reasonably aligned. - */ - if (ISSET(FTS_NOSTAT)) - len = sizeof(FTSENT) + namelen + 1; - else - len = sizeof(struct ftsent_withstat) + namelen + 1; - - if ((p = malloc(len)) == NULL) - return (NULL); - - if (ISSET(FTS_NOSTAT)) { - p->fts_name = (char *)(p + 1); - p->fts_statp = NULL; - } else { - p->fts_name = (char *)((struct ftsent_withstat *)p + 1); - p->fts_statp = &((struct ftsent_withstat *)p)->statbuf; - } - - /* Copy the name and guarantee NUL termination. */ - memcpy(p->fts_name, name, namelen); - p->fts_name[namelen] = '\0'; - p->fts_namelen = namelen; - p->fts_path = sp->fts_path; - p->fts_errno = 0; - p->fts_flags = 0; - p->fts_instr = FTS_NOINSTR; - p->fts_number = 0; - p->fts_pointer = NULL; - p->fts_fts = sp; - return (p); -} - -static void -fts_lfree(head) - FTSENT *head; -{ - FTSENT *p; - - /* Free a linked list of structures. */ - while ((p = head)) { - head = head->fts_link; - free(p); - } -} - -/* - * Allow essentially unlimited paths; find, rm, ls should all work on any tree. - * Most systems will allow creation of paths much longer than MAXPATHLEN, even - * though the kernel won't resolve them. Add the size (not just what's needed) - * plus 256 bytes so don't realloc the path 2 bytes at a time. - */ -static int -fts_palloc(sp, more) - FTS *sp; - size_t more; -{ - - sp->fts_pathlen += more + 256; - /* - * Check for possible wraparound. In an FTS, fts_pathlen is - * a signed int but in an FTSENT it is an unsigned short. - * We limit fts_pathlen to USHRT_MAX to be safe in both cases. - */ - if (sp->fts_pathlen < 0 || sp->fts_pathlen >= USHRT_MAX) { - if (sp->fts_path) - free(sp->fts_path); - sp->fts_path = NULL; - errno = ENAMETOOLONG; - return (1); - } - sp->fts_path = reallocf(sp->fts_path, sp->fts_pathlen); - return (sp->fts_path == NULL); -} - -/* - * When the path is realloc'd, have to fix all of the pointers in structures - * already returned. - */ -static void -fts_padjust(sp, head) - FTS *sp; - FTSENT *head; -{ - FTSENT *p; - char *addr = sp->fts_path; - -#define ADJUST(p) do { \ - if ((p)->fts_accpath != (p)->fts_name) { \ - (p)->fts_accpath = \ - (char *)addr + ((p)->fts_accpath - (p)->fts_path); \ - } \ - (p)->fts_path = addr; \ -} while (0) - /* Adjust the current set of children. */ - for (p = sp->fts_child; p; p = p->fts_link) - ADJUST(p); - - /* Adjust the rest of the tree, including the current level. */ - for (p = head; p->fts_level >= FTS_ROOTLEVEL;) { - ADJUST(p); - p = p->fts_link ? p->fts_link : p->fts_parent; - } -} - -static size_t -fts_maxarglen(argv) - char * const *argv; -{ - size_t len, max; - - for (max = 0; *argv; ++argv) - if ((len = strlen(*argv)) > max) - max = len; - return (max + 1); -} - -/* - * Change to dir specified by fd or p->fts_accpath without getting - * tricked by someone changing the world out from underneath us. - * Assumes p->fts_dev and p->fts_ino are filled in. - */ -static int -fts_safe_changedir(sp, p, fd, path) - FTS *sp; - FTSENT *p; - int fd; - const char *path; -{ - int ret, oerrno, newfd; - struct __stat64 sb; - - newfd = fd; - if (ISSET(FTS_NOCHDIR)) - return (0); - if (fd < 0 && (newfd = _open(path, O_RDONLY, 0)) < 0) - return (-1); - if (fstat64(newfd, &sb)) { - ret = -1; - goto bail; - } - if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) { - errno = ENOENT; /* disinformation */ - ret = -1; - goto bail; - } - ret = fchdir(newfd); -bail: - oerrno = errno; - if (fd < 0) - (void)_close(newfd); - errno = oerrno; - return (ret); -} - -/* - * Check if the filesystem for "ent" has UFS-style links. - */ -static int -fts_ufslinks(FTS *sp, const FTSENT *ent) -{ - struct _fts_private *priv; -#ifndef __CYGWIN__ - const char **cpp; -#endif - - priv = (struct _fts_private *)sp; - /* - * If this node's device is different from the previous, grab - * the filesystem information, and decide on the reliability - * of the link information from this filesystem for stat(2) - * avoidance. - */ - if (priv->ftsp_dev != ent->fts_dev) { - if (statfs(ent->fts_path, &priv->ftsp_statfs) != -1) { - priv->ftsp_dev = ent->fts_dev; -#ifdef __CYGWIN__ - /* The link count is reliable in Cygwin's directory - stat structures, unless the link count is 1. - This indicates a remote filesystem on which Cygwin - refuses to count the directory links for speed. */ - priv->ftsp_linksreliable = (ent->fts_dev == 1) ? 0 : 1; -#else - priv->ftsp_linksreliable = 0; - for (cpp = ufslike_filesystems; *cpp; cpp++) { - if (strcmp(priv->ftsp_statfs.f_fstypename, - *cpp) == 0) { - priv->ftsp_linksreliable = 1; - break; - } - } -#endif - } else { - priv->ftsp_linksreliable = 0; - } - } - return (priv->ftsp_linksreliable); -} diff --git a/winsup/cygwin/libc/ftw.c b/winsup/cygwin/libc/ftw.c deleted file mode 100644 index 2589e5b4f..000000000 --- a/winsup/cygwin/libc/ftw.c +++ /dev/null @@ -1,102 +0,0 @@ -/* $OpenBSD: ftw.c,v 1.4 2004/07/07 16:05:23 millert Exp $ */ - -/* - * Copyright (c) 2003, 2004 Todd C. Miller <Todd.Miller@courtesan.com> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F39502-99-1-0512. - */ - -#if 0 -#if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$OpenBSD: ftw.c,v 1.4 2004/07/07 16:05:23 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ -#endif - -#ifdef __CYGWIN__ -#include "winsup.h" -#endif -#include <sys/cdefs.h> -#if 0 -__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/gen/ftw.c,v 1.4 2004/08/24 13:00:55 tjr Exp $"); -#endif -#include <sys/types.h> -#include <sys/stat.h> -#include <errno.h> -#include <fts.h> -#include <ftw.h> -#include <limits.h> - -int -ftw(const char *path, int (*fn)(const char *, const struct __stat64 *, int), - int nfds) -{ - char * const paths[2] = { (char *)path, NULL }; - FTSENT *cur; - FTS *ftsp; - int error = 0, fnflag, sverrno; - - /* XXX - nfds is currently unused */ - if (nfds < 1 || nfds > OPEN_MAX) { - errno = EINVAL; - return (-1); - } - - ftsp = fts_open(paths, FTS_LOGICAL | FTS_COMFOLLOW | FTS_NOCHDIR, NULL); - if (ftsp == NULL) - return (-1); - while ((cur = fts_read(ftsp)) != NULL) { - switch (cur->fts_info) { - case FTS_D: - fnflag = FTW_D; - break; - case FTS_DNR: - fnflag = FTW_DNR; - break; - case FTS_DP: - /* we only visit in preorder */ - continue; - case FTS_F: - case FTS_DEFAULT: - fnflag = FTW_F; - break; - case FTS_NS: - case FTS_NSOK: - case FTS_SLNONE: - fnflag = FTW_NS; - break; - case FTS_SL: - fnflag = FTW_SL; - break; - case FTS_DC: - errno = ELOOP; - /* FALLTHROUGH */ - default: - error = -1; - goto done; - } - error = fn(cur->fts_path, cur->fts_statp, fnflag); - if (error != 0) - break; - } -done: - sverrno = errno; - if (fts_close(ftsp) != 0 && error == 0) - error = -1; - else - errno = sverrno; - return (error); -} diff --git a/winsup/cygwin/libc/getopt.c b/winsup/cygwin/libc/getopt.c deleted file mode 100644 index 0ed46310e..000000000 --- a/winsup/cygwin/libc/getopt.c +++ /dev/null @@ -1,548 +0,0 @@ -/* $OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert Exp $ */ -/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ - -/* - * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F39502-99-1-0512. - */ -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Dieter Baron and Thomas Klausner. - * - * 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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: getopt_long.c,v 1.16 2004/02/04 18:17:25 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include <err.h> -#include <errno.h> -#include <getopt.h> -#include <stdlib.h> -#include <string.h> - -#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */ - -#ifdef REPLACE_GETOPT -int opterr = 1; /* if error message should be printed */ -int optind = 1; /* index into parent argv vector */ -int optopt = '?'; /* character checked for validity */ -int optreset; /* reset getopt */ -char *optarg; /* argument associated with option */ -#endif - -#define PRINT_ERROR ((opterr) && (*options != ':')) - -#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ -#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ -#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ - -/* return values */ -#define BADCH (int)'?' -#define BADARG ((*options == ':') ? (int)':' : (int)'?') -#define INORDER (int)1 - -#ifdef __CYGWIN__ -static char EMSG[] = ""; -#else -#define EMSG "" -#endif - -static int getopt_internal(int, char * const *, const char *, - const struct option *, int *, int); -static int parse_long_options(char * const *, const char *, - const struct option *, int *, int); -static int gcd(int, int); -static void permute_args(int, int, int, char * const *); - -static char *place = EMSG; /* option letter processing */ - -/* XXX: set optreset to 1 rather than these two */ -static int nonopt_start = -1; /* first non option argument (for permute) */ -static int nonopt_end = -1; /* first option after non options (for permute) */ - -/* Error messages */ -static const char recargchar[] = "option requires an argument -- %c"; -static const char recargstring[] = "option requires an argument -- %s"; -static const char ambig[] = "ambiguous option -- %.*s"; -static const char noarg[] = "option doesn't take an argument -- %.*s"; -static const char illoptchar[] = "unknown option -- %c"; -static const char illoptstring[] = "unknown option -- %s"; - -/* - * Compute the greatest common divisor of a and b. - */ -static int -gcd(int a, int b) -{ - int c; - - c = a % b; - while (c != 0) { - a = b; - b = c; - c = a % b; - } - - return (b); -} - -/* - * Exchange the block from nonopt_start to nonopt_end with the block - * from nonopt_end to opt_end (keeping the same order of arguments - * in each block). - */ -static void -permute_args(int panonopt_start, int panonopt_end, int opt_end, - char * const *nargv) -{ - int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; - char *swap; - - /* - * compute lengths of blocks and number and size of cycles - */ - nnonopts = panonopt_end - panonopt_start; - nopts = opt_end - panonopt_end; - ncycle = gcd(nnonopts, nopts); - cyclelen = (opt_end - panonopt_start) / ncycle; - - for (i = 0; i < ncycle; i++) { - cstart = panonopt_end+i; - pos = cstart; - for (j = 0; j < cyclelen; j++) { - if (pos >= panonopt_end) - pos -= nnonopts; - else - pos += nopts; - swap = nargv[pos]; - /* LINTED const cast */ - ((char **) nargv)[pos] = nargv[cstart]; - /* LINTED const cast */ - ((char **)nargv)[cstart] = swap; - } - } -} - -/* - * parse_long_options -- - * Parse long options in argc/argv argument vector. - * Returns -1 if short_too is set and the option does not match long_options. - */ -static int -parse_long_options(char * const *nargv, const char *options, - const struct option *long_options, int *idx, int short_too) -{ - char *current_argv, *has_equal; - size_t current_argv_len; - int i, match; - - current_argv = place; - match = -1; - - optind++; - - if ((has_equal = strchr(current_argv, '=')) != NULL) { - /* argument found (--option=arg) */ - current_argv_len = has_equal - current_argv; - has_equal++; - } else - current_argv_len = strlen(current_argv); - - for (i = 0; long_options[i].name; i++) { - /* find matching long option */ - if (strncmp(current_argv, long_options[i].name, - current_argv_len)) - continue; - - if (strlen(long_options[i].name) == current_argv_len) { - /* exact match */ - match = i; - break; - } - /* - * If this is a known short option, don't allow - * a partial match of a single character. - */ - if (short_too && current_argv_len == 1) - continue; - - if (match == -1) /* partial match */ - match = i; - else { - /* ambiguous abbreviation */ - if (PRINT_ERROR) - warnx(ambig, (int)current_argv_len, - current_argv); - optopt = 0; - return (BADCH); - } - } - if (match != -1) { /* option found */ - if (long_options[match].has_arg == no_argument - && has_equal) { - if (PRINT_ERROR) - warnx(noarg, (int)current_argv_len, - current_argv); - /* - * XXX: GNU sets optopt to val regardless of flag - */ - if (long_options[match].flag == NULL) - optopt = long_options[match].val; - else - optopt = 0; - return (BADARG); - } - if (long_options[match].has_arg == required_argument || - long_options[match].has_arg == optional_argument) { - if (has_equal) - optarg = has_equal; - else if (long_options[match].has_arg == - required_argument) { - /* - * optional argument doesn't use next nargv - */ - optarg = nargv[optind++]; - } - } - if ((long_options[match].has_arg == required_argument) - && (optarg == NULL)) { - /* - * Missing argument; leading ':' indicates no error - * should be generated. - */ - if (PRINT_ERROR) - warnx(recargstring, - current_argv); - /* - * XXX: GNU sets optopt to val regardless of flag - */ - if (long_options[match].flag == NULL) - optopt = long_options[match].val; - else - optopt = 0; - --optind; - return (BADARG); - } - } else { /* unknown option */ - if (short_too) { - --optind; - return (-1); - } - if (PRINT_ERROR) - warnx(illoptstring, current_argv); - optopt = 0; - return (BADCH); - } - if (idx) - *idx = match; - if (long_options[match].flag) { - *long_options[match].flag = long_options[match].val; - return (0); - } else - return (long_options[match].val); -} - -/* - * getopt_internal -- - * Parse argc/argv argument vector. Called by user level routines. - */ -static int -getopt_internal(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx, int flags) -{ - char *oli; /* option letter list index */ - int optchar, short_too; - static int posixly_correct = -1; - - if (options == NULL) - return (-1); - - /* - * Disable GNU extensions if POSIXLY_CORRECT is set or options - * string begins with a '+'. - */ - if (posixly_correct == -1) - posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); - if (posixly_correct || *options == '+') - flags &= ~FLAG_PERMUTE; - else if (*options == '-') - flags |= FLAG_ALLARGS; - if (*options == '+' || *options == '-') - options++; - - /* - * XXX Some GNU programs (like cvs) set optind to 0 instead of - * XXX using optreset. Work around this braindamage. - */ - if (optind == 0) - optind = optreset = 1; - - optarg = NULL; - if (optreset) - nonopt_start = nonopt_end = -1; -start: - if (optreset || !*place) { /* update scanning pointer */ - optreset = 0; - if (optind >= nargc) { /* end of argument vector */ - place = EMSG; - if (nonopt_end != -1) { - /* do permutation, if we have to */ - permute_args(nonopt_start, nonopt_end, - optind, nargv); - optind -= nonopt_end - nonopt_start; - } - else if (nonopt_start != -1) { - /* - * If we skipped non-options, set optind - * to the first of them. - */ - optind = nonopt_start; - } - nonopt_start = nonopt_end = -1; - return (-1); - } - if (*(place = nargv[optind]) != '-' || - (place[1] == '\0' && strchr(options, '-') == NULL)) { - place = EMSG; /* found non-option */ - if (flags & FLAG_ALLARGS) { - /* - * GNU extension: - * return non-option as argument to option 1 - */ - optarg = nargv[optind++]; - return (INORDER); - } - if (!(flags & FLAG_PERMUTE)) { - /* - * If no permutation wanted, stop parsing - * at first non-option. - */ - return (-1); - } - /* do permutation */ - if (nonopt_start == -1) - nonopt_start = optind; - else if (nonopt_end != -1) { - permute_args(nonopt_start, nonopt_end, - optind, nargv); - nonopt_start = optind - - (nonopt_end - nonopt_start); - nonopt_end = -1; - } - optind++; - /* process next argument */ - goto start; - } - if (nonopt_start != -1 && nonopt_end == -1) - nonopt_end = optind; - - /* - * If we have "-" do nothing, if "--" we are done. - */ - if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { - optind++; - place = EMSG; - /* - * We found an option (--), so if we skipped - * non-options, we have to permute. - */ - if (nonopt_end != -1) { - permute_args(nonopt_start, nonopt_end, - optind, nargv); - optind -= nonopt_end - nonopt_start; - } - nonopt_start = nonopt_end = -1; - return (-1); - } - } - - /* - * Check long options if: - * 1) we were passed some - * 2) the arg is not just "-" - * 3) either the arg starts with -- we are getopt_long_only() - */ - if (long_options != NULL && place != nargv[optind] && - (*place == '-' || (flags & FLAG_LONGONLY))) { - short_too = 0; - if (*place == '-') - place++; /* --foo long option */ - else if (*place != ':' && strchr(options, *place) != NULL) - short_too = 1; /* could be short option too */ - - optchar = parse_long_options(nargv, options, long_options, - idx, short_too); - if (optchar != -1) { - place = EMSG; - return (optchar); - } - } - - if ((optchar = (int)*place++) == (int)':' || - (optchar == (int)'-' && *place != '\0') || - (oli = strchr(options, optchar)) == NULL) { - /* - * If the user specified "-" and '-' isn't listed in - * options, return -1 (non-option) as per POSIX. - * Otherwise, it is an unknown option character (or ':'). - */ - if (optchar == (int)'-' && *place == '\0') - return (-1); - if (!*place) - ++optind; - if (PRINT_ERROR) - warnx(illoptchar, optchar); - optopt = optchar; - return (BADCH); - } - if (long_options != NULL && optchar == 'W' && oli[1] == ';') { - /* -W long-option */ - if (*place) /* no space */ - /* NOTHING */; - else if (++optind >= nargc) { /* no arg */ - place = EMSG; - if (PRINT_ERROR) - warnx(recargchar, optchar); - optopt = optchar; - return (BADARG); - } else /* white space */ - place = nargv[optind]; - optchar = parse_long_options(nargv, options, long_options, - idx, 0); - place = EMSG; - return (optchar); - } - if (*++oli != ':') { /* doesn't take argument */ - if (!*place) - ++optind; - } else { /* takes (optional) argument */ - optarg = NULL; - if (*place) /* no white space */ - optarg = place; - /* XXX: disable test for :: if PC? (GNU doesn't) */ - else if (oli[1] != ':') { /* arg not optional */ - if (++optind >= nargc) { /* no arg */ - place = EMSG; - if (PRINT_ERROR) - warnx(recargchar, optchar); - optopt = optchar; - return (BADARG); - } else - optarg = nargv[optind]; - } else if (!(flags & FLAG_PERMUTE)) { - /* - * If permutation is disabled, we can accept an - * optional arg separated by whitespace. - */ - if (optind + 1 < nargc) - optarg = nargv[++optind]; - } - place = EMSG; - ++optind; - } - /* dump back option letter */ - return (optchar); -} - -#ifdef REPLACE_GETOPT -/* - * getopt -- - * Parse argc/argv argument vector. - * - * [eventually this will replace the BSD getopt] - */ -int -getopt(int nargc, char * const *nargv, const char *options) -{ - - /* - * We dont' pass FLAG_PERMUTE to getopt_internal() since - * the BSD getopt(3) (unlike GNU) has never done this. - * - * Furthermore, since many privileged programs call getopt() - * before dropping privileges it makes sense to keep things - * as simple (and bug-free) as possible. - */ - return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); -} -#endif /* REPLACE_GETOPT */ - -/* - * getopt_long -- - * Parse argc/argv argument vector. - */ -int -getopt_long(nargc, nargv, options, long_options, idx) - int nargc; - char * const *nargv; - const char *options; - const struct option *long_options; - int *idx; -{ - - return (getopt_internal(nargc, nargv, options, long_options, idx, - FLAG_PERMUTE)); -} - -/* - * getopt_long_only -- - * Parse argc/argv argument vector. - */ -int -getopt_long_only(nargc, nargv, options, long_options, idx) - int nargc; - char * const *nargv; - const char *options; - const struct option *long_options; - int *idx; -{ - - return (getopt_internal(nargc, nargv, options, long_options, idx, - FLAG_PERMUTE|FLAG_LONGONLY)); -} diff --git a/winsup/cygwin/libc/inet_addr.c b/winsup/cygwin/libc/inet_addr.c deleted file mode 100644 index 5716ee9c3..000000000 --- a/winsup/cygwin/libc/inet_addr.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 1983, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -/* - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Portions Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; -static const char rcsid[] = "$Id$"; -#endif /* LIBC_SCCS and not lint */ -#include <sys/cdefs.h> -#ifndef __CYGWIN__ -__FBSDID("$FreeBSD$"); -#else -#define __INSIDE_CYGWIN__ -#define __INSIDE_CYGWIN_NET__ -#endif - -#ifndef __CYGWIN__ -#include "port_before.h" -#endif - -#include <sys/types.h> -#include <sys/param.h> - -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <ctype.h> - -#ifndef __CYGWIN__ -#include "port_after.h" -#endif - -/* - * Check whether "cp" is a valid ascii representation - * of an Internet address and convert to a binary address. - * Returns 1 if the address is valid, 0 if not. - * This replaces inet_addr, the return value from which - * cannot distinguish between failure and a local broadcast address. - */ -extern int -cygwin_inet_aton(const char *cp, struct in_addr *addr) { - u_long val; - int base, n; - char c; - u_int8_t parts[4]; - u_int8_t *pp = parts; - int digit; - - c = *cp; - for (;;) { - /* - * Collect number up to ``.''. - * Values are specified as for C: - * 0x=hex, 0=octal, isdigit=decimal. - */ - if (!isdigit((unsigned char)c)) - return (0); - val = 0; base = 10; digit = 0; - if (c == '0') { - c = *++cp; - if (c == 'x' || c == 'X') - base = 16, c = *++cp; - else { - base = 8; - digit = 1 ; - } - } - for (;;) { - if (isascii(c) && isdigit((unsigned char)c)) { - if (base == 8 && (c == '8' || c == '9')) - return (0); - val = (val * base) + (c - '0'); - c = *++cp; - digit = 1; - } else if (base == 16 && isascii(c) && - isxdigit((unsigned char)c)) { - val = (val << 4) | - (c + 10 - (islower((unsigned char)c) ? 'a' : 'A')); - c = *++cp; - digit = 1; - } else - break; - } - if (c == '.') { - /* - * Internet format: - * a.b.c.d - * a.b.c (with c treated as 16 bits) - * a.b (with b treated as 24 bits) - */ - if (pp >= parts + 3 || val > 0xffU) - return (0); - *pp++ = val; - c = *++cp; - } else - break; - } - /* - * Check for trailing characters. - */ - if (c != '\0' && (!isascii(c) || !isspace((unsigned char)c))) - return (0); - /* - * Did we get a valid digit? - */ - if (!digit) - return (0); - /* - * Concoct the address according to - * the number of parts specified. - */ - n = pp - parts + 1; - switch (n) { - case 1: /* a -- 32 bits */ - break; - - case 2: /* a.b -- 8.24 bits */ - if (val > 0xffffffU) - return (0); - val |= parts[0] << 24; - break; - - case 3: /* a.b.c -- 8.8.16 bits */ - if (val > 0xffffU) - return (0); - val |= (parts[0] << 24) | (parts[1] << 16); - break; - - case 4: /* a.b.c.d -- 8.8.8.8 bits */ - if (val > 0xffU) - return (0); - val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); - break; - } - if (addr != NULL) - addr->s_addr = htonl(val); - return (1); -} - -/* - * Ascii internet address interpretation routine. - * The value returned is in network order. - */ -in_addr_t /* XXX should be struct in_addr :( */ -cygwin_inet_addr(const char *cp) { - struct in_addr val; - - if (cygwin_inet_aton(cp, &val)) - return (val.s_addr); - return (INADDR_NONE); -} - -#ifndef __CYGWIN__ -/* - * Weak aliases for applications that use certain private entry points, - * and fail to include <arpa/inet.h>. - */ -#undef inet_addr -__weak_reference(__inet_addr, inet_addr); -#undef inet_aton -__weak_reference(__inet_aton, inet_aton); -#endif diff --git a/winsup/cygwin/libc/inet_network.c b/winsup/cygwin/libc/inet_network.c deleted file mode 100644 index 70625fd7f..000000000 --- a/winsup/cygwin/libc/inet_network.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 1983, 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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static const char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ -#include <sys/cdefs.h> -#ifndef __CYGWIN__ -__FBSDID("$FreeBSD$"); -#else -#define __INSIDE_CYGWIN__ -#define __INSIDE_CYGWIN_NET__ -#endif - -#ifndef __CYGWIN__ -#include "port_before.h" -#endif - -#include <sys/types.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <ctype.h> - -#ifndef __CYGWIN__ -#include "port_after.h" -#endif - -/* - * Internet network address interpretation routine. - * The library routines call this routine to interpret - * network numbers. - */ -in_addr_t -cygwin_inet_network(cp) - const char *cp; -{ - in_addr_t val, base, n; - char c; - in_addr_t parts[4], *pp = parts; - int i, digit; - -again: - val = 0; base = 10; digit = 0; - if (*cp == '0') - digit = 1, base = 8, cp++; - if (*cp == 'x' || *cp == 'X') - base = 16, cp++; - while ((c = *cp) != 0) { - if (isdigit((unsigned char)c)) { - if (base == 8U && (c == '8' || c == '9')) - return (INADDR_NONE); - val = (val * base) + (c - '0'); - cp++; - digit = 1; - continue; - } - if (base == 16U && isxdigit((unsigned char)c)) { - val = (val << 4) + - (c + 10 - (islower((unsigned char)c) ? 'a' : 'A')); - cp++; - digit = 1; - continue; - } - break; - } - if (!digit) - return (INADDR_NONE); - if (*cp == '.') { - if (pp >= parts + 4 || val > 0xffU) - return (INADDR_NONE); - *pp++ = val, cp++; - goto again; - } - if (*cp && !isspace(*cp&0xff)) - return (INADDR_NONE); - *pp++ = val; - n = pp - parts; - if (n > 4U) - return (INADDR_NONE); - for (val = 0, i = 0; i < n; i++) { - val <<= 8; - val |= parts[i] & 0xff; - } - return (val); -} - -#ifndef __CYGWIN__ -/* - * Weak aliases for applications that use certain private entry points, - * and fail to include <arpa/inet.h>. - */ -#undef inet_network -__weak_reference(__inet_network, inet_network); -#endif diff --git a/winsup/cygwin/libc/memmem.cc b/winsup/cygwin/libc/memmem.cc deleted file mode 100644 index cd9dc33d3..000000000 --- a/winsup/cygwin/libc/memmem.cc +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * Copyright (c) 2005 Pascal Gloor <pascal.gloor@spale.com> - * - * 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. 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 AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -#if 0 -__FBSDID("$FreeBSD: src/lib/libc/string/memmem.c,v 1.1 2005/08/25 18:26:58 andre Exp $"); -#endif - -#include <string.h> - -/* Find the first occurrence of the byte string s in byte string l. - */ - -extern "C" void * -memmem (const void *l, size_t l_len, - const void *s, size_t s_len) -{ - register char *cur, *last; - const char *cl = (const char *)l; - const char *cs = (const char *)s; - - /* we need something to compare */ - if (l_len == 0 || s_len == 0) - return NULL; - - /* "s" must be smaller or equal to "l" */ - if (l_len < s_len) - return NULL; - - /* special case where s_len == 1 */ - if (s_len == 1) - return memchr (l, (int) *cs, l_len); - - /* the last position where its possible to find "s" in "l" */ - last = (char *) cl + l_len - s_len; - - for (cur = (char *) cl; cur <= last; cur++) - if (cur[0] == cs[0] && memcmp (cur, cs, s_len) == 0) - return cur; - - return NULL; -} diff --git a/winsup/cygwin/libc/nftw.c b/winsup/cygwin/libc/nftw.c deleted file mode 100644 index f7c06b29d..000000000 --- a/winsup/cygwin/libc/nftw.c +++ /dev/null @@ -1,121 +0,0 @@ -/* $OpenBSD: nftw.c,v 1.4 2004/07/07 16:05:23 millert Exp $ */ - -/* - * Copyright (c) 2003, 2004 Todd C. Miller <Todd.Miller@courtesan.com> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Sponsored in part by the Defense Advanced Research Projects - * Agency (DARPA) and Air Force Research Laboratory, Air Force - * Materiel Command, USAF, under agreement number F39502-99-1-0512. - */ - -#if 0 -#if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$OpenBSD: nftw.c,v 1.4 2004/07/07 16:05:23 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ -#endif - -#ifdef __CYGWIN__ -#include "winsup.h" -#endif -#include <sys/cdefs.h> -#if 0 -__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/gen/nftw.c,v 1.1.2.1 2004/08/29 06:10:53 tjr Exp $"); -#endif -#include <sys/types.h> -#include <sys/stat.h> -#include <errno.h> -#include <fts.h> -#include <ftw.h> -#include <limits.h> - -int -nftw(const char *path, int (*fn)(const char *, const struct __stat64 *, int, - struct FTW *), int nfds, int ftwflags) -{ - char * const paths[2] = { (char *)path, NULL }; - struct FTW ftw; - FTSENT *cur; - FTS *ftsp; - int error = 0, ftsflags, fnflag, postorder, sverrno; - - /* XXX - nfds is currently unused */ - if (nfds < 1 || nfds > OPEN_MAX) { - errno = EINVAL; - return (-1); - } - - ftsflags = FTS_COMFOLLOW; - if (!(ftwflags & FTW_CHDIR)) - ftsflags |= FTS_NOCHDIR; - if (ftwflags & FTW_MOUNT) - ftsflags |= FTS_XDEV; - if (ftwflags & FTW_PHYS) - ftsflags |= FTS_PHYSICAL; - else - ftsflags |= FTS_LOGICAL; - postorder = (ftwflags & FTW_DEPTH) != 0; - ftsp = fts_open(paths, ftsflags, NULL); - if (ftsp == NULL) - return (-1); - while ((cur = fts_read(ftsp)) != NULL) { - switch (cur->fts_info) { - case FTS_D: - if (postorder) - continue; - fnflag = FTW_D; - break; - case FTS_DNR: - fnflag = FTW_DNR; - break; - case FTS_DP: - if (!postorder) - continue; - fnflag = FTW_DP; - break; - case FTS_F: - case FTS_DEFAULT: - fnflag = FTW_F; - break; - case FTS_NS: - case FTS_NSOK: - fnflag = FTW_NS; - break; - case FTS_SL: - fnflag = FTW_SL; - break; - case FTS_SLNONE: - fnflag = FTW_SLN; - break; - case FTS_DC: - errno = ELOOP; - /* FALLTHROUGH */ - default: - error = -1; - goto done; - } - ftw.base = cur->fts_pathlen - cur->fts_namelen; - ftw.level = cur->fts_level; - error = fn(cur->fts_path, cur->fts_statp, fnflag, &ftw); - if (error != 0) - break; - } -done: - sverrno = errno; - if (fts_close(ftsp) != 0 && error == 0) - error = -1; - else - errno = sverrno; - return (error); -} diff --git a/winsup/cygwin/libc/rcmd.cc b/winsup/cygwin/libc/rcmd.cc deleted file mode 100644 index 0e484c515..000000000 --- a/winsup/cygwin/libc/rcmd.cc +++ /dev/null @@ -1,782 +0,0 @@ -/* - * Copyright (c) 1983, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94"; -#endif /* LIBC_SCCS and not lint */ -#include <sys/cdefs.h> -#ifndef __CYGWIN__ -__FBSDID("$FreeBSD$"); -#else -#define __INSIDE_CYGWIN_NET__ -#include "winsup.h" -#endif - -#ifndef __CYGWIN__ -#include "namespace.h" -#endif -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/stat.h> - -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <signal.h> -#include <fcntl.h> -#include <netdb.h> -#include <stdlib.h> -#include <unistd.h> -#include <pwd.h> -#include <errno.h> -#include <stdio.h> -#include <ctype.h> -#include <string.h> -#ifndef __CYGWIN__ -#include <rpc/rpc.h> -#endif -#ifdef YP -#include <rpcsvc/yp_prot.h> -#include <rpcsvc/ypclnt.h> -#endif -#ifndef __CYGWIN__ -#include <arpa/nameser.h> -#include "un-namespace.h" -#endif - -#ifndef __CYGWIN__ -extern int innetgr( const char *, const char *, const char *, const char * ); - -#define max(a, b) ((a > b) ? a : b) -#else -#include "wininet.h" -#include "cygwin/in6.h" - -#ifndef _PATH_HEQUIV -# define _PATH_HEQUIV "/etc/hosts.equiv" -#endif - -#define innetgr(a,b,c,d) (0) - -extern int rcmdsh(char **, int, const char *, const char *, const char *, - const char *); - -extern "C" { - int cygwin_accept (int, struct sockaddr *, socklen_t *); - int cygwin_bindresvport_sa (int, struct sockaddr *); - int cygwin_connect (int, const struct sockaddr *, socklen_t); - void cygwin_freeaddrinfo (struct addrinfo *); - const char * cygwin_gai_strerror (int); - int cygwin_getaddrinfo (const char *, const char *, const struct addrinfo *, - struct addrinfo **); - int cygwin_getnameinfo (const struct sockaddr *, socklen_t, char *, size_t, - char *, size_t, int); - struct servent *cygwin_getservbyname (const char *, const char *); - int cygwin_listen (int, int); - int cygwin_rresvport_af(int *alport, int family); - int cygwin_select (int, fd_set *, fd_set *, fd_set *, struct timeval *); - int cygwin_socket (int, int, int); - int seteuid32 (__uid32_t); -} -#endif - -#ifndef __CYGWIN__ -static int __ivaliduser(FILE *, u_int32_t, const char *, const char *); -static int __ivaliduser_af(FILE *,const void *, const char *, const char *, - int, int); -#endif -static int __ivaliduser_sa(FILE *, const struct sockaddr *, socklen_t, - const char *, const char *); -static int __icheckhost(const struct sockaddr *, socklen_t, const char *); - -char paddr[NI_MAXHOST]; - -extern "C" int -cygwin_rcmd_af(char **ahost, in_port_t rport, const char *locuser, - const char *remuser, const char *cmd, int *fd2p, int af) -{ - struct addrinfo hints, *res, *ai; - struct sockaddr_storage from; - fd_set reads; - sigset_t oldmask, newmask; - pid_t pid; - int s, aport, lport, timo, error; - char c;//, *p; - int refused, nres; - char num[8]; - static char canonnamebuf[INTERNET_MAX_HOST_NAME_LENGTH + 1]; /* is it proper here? */ -#ifndef __CYGWIN__ - /* call rcmdsh() with specified remote shell if appropriate. */ - if (!issetugid() && (p = getenv("RSH"))) { - struct servent *sp = cygwin_getservbyname("shell", "tcp"); - - if (sp && sp->s_port == rport) - return (rcmdsh(ahost, rport, locuser, remuser, - cmd, p)); - } - - /* use rsh(1) if non-root and remote port is shell. */ - if (geteuid()) { - struct servent *sp = cygwin_getservbyname("shell", "tcp"); - - if (sp && sp->s_port == rport) - return (rcmdsh(ahost, rport, locuser, remuser, - cmd, NULL)); - } -#endif - pid = getpid(); - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME; - hints.ai_family = af; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = 0; - (void)snprintf(num, sizeof(num), "%d", ntohs(rport)); - error = cygwin_getaddrinfo(*ahost, num, &hints, &res); - if (error) { - fprintf(stderr, "rcmd: getaddrinfo: %s\n", - cygwin_gai_strerror(error)); - if (error == EAI_SYSTEM) - fprintf(stderr, "rcmd: getaddrinfo: %s\n", - strerror(errno)); - return (-1); - } - - if (res->ai_canonname - && strlen(res->ai_canonname) + 1 < sizeof(canonnamebuf)) { - strncpy(canonnamebuf, res->ai_canonname, sizeof(canonnamebuf)); - *ahost = canonnamebuf; - } - nres = 0; - for (ai = res; ai; ai = ai->ai_next) - nres++; - ai = res; - refused = 0; - sigemptyset(&newmask); - sigaddset(&newmask, SIGURG); - sigprocmask(SIG_BLOCK, (const sigset_t *)&newmask, &oldmask); - for (timo = 1, lport = IPPORT_RESERVED - 1;;) { - s = cygwin_rresvport_af(&lport, ai->ai_family); - if (s < 0) { - if (errno != EAGAIN && ai->ai_next) { - ai = ai->ai_next; - continue; - } - if (errno == EAGAIN) - (void)fprintf(stderr, - "rcmd: socket: All ports in use\n"); - else - (void)fprintf(stderr, "rcmd: socket: %s\n", - strerror(errno)); - cygwin_freeaddrinfo(res); - sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, - NULL); - return (-1); - } - fcntl(s, F_SETOWN, pid); - if (cygwin_connect(s, ai->ai_addr, ai->ai_addrlen) >= 0) - break; - (void)close(s); - if (errno == EADDRINUSE) { - lport--; - continue; - } - if (errno == ECONNREFUSED) - refused = 1; - if (ai->ai_next == NULL && (!refused || timo > 16)) { - (void)fprintf(stderr, "%s: %s\n", - *ahost, strerror(errno)); - cygwin_freeaddrinfo(res); - sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, - NULL); - return (-1); - } - if (nres > 1) { - int oerrno = errno; - - cygwin_getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr, - sizeof(paddr), NULL, 0, NI_NUMERICHOST); - (void)fprintf(stderr, "connect to address %s: ", - paddr); - errno = oerrno; - perror(0); - } - if ((ai = ai->ai_next) == NULL) { - /* refused && timo <= 16 */ - struct timespec time_to_sleep, time_remaining; - - time_to_sleep.tv_sec = timo; - time_to_sleep.tv_nsec = 0; - (void)nanosleep(&time_to_sleep, &time_remaining); - timo *= 2; - ai = res; - refused = 0; - } - if (nres > 1) { - cygwin_getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr, - sizeof(paddr), NULL, 0, NI_NUMERICHOST); - fprintf(stderr, "Trying %s...\n", paddr); - } - } - lport--; - if (fd2p == 0) { - write(s, "", 1); - lport = 0; - } else { - int s2 = cygwin_rresvport_af(&lport, ai->ai_family), s3; - socklen_t len = ai->ai_addrlen; - int nfds; - - if (s2 < 0) - goto bad; - cygwin_listen(s2, 1); - (void)snprintf(num, sizeof(num), "%d", lport); - if (write(s, num, strlen(num)+1) != (int)strlen(num)+1) { - (void)fprintf(stderr, - "rcmd: write (setting up stderr): %s\n", - strerror(errno)); - (void)close(s2); - goto bad; - } - nfds = max(s, s2)+1; - if(nfds > FD_SETSIZE) { - fprintf(stderr, "rcmd: too many files\n"); - (void)close(s2); - goto bad; - } -again: - FD_ZERO(&reads); - FD_SET(s, &reads); - FD_SET(s2, &reads); - errno = 0; - if (cygwin_select(nfds, &reads, 0, 0, 0) < 1 || !FD_ISSET(s2, &reads)){ - if (errno != 0) - (void)fprintf(stderr, - "rcmd: select (setting up stderr): %s\n", - strerror(errno)); - else - (void)fprintf(stderr, - "select: protocol failure in circuit setup\n"); - (void)close(s2); - goto bad; - } - s3 = cygwin_accept(s2, (struct sockaddr *)&from, &len); - switch (from.ss_family) { - case AF_INET: - aport = ntohs(((struct sockaddr_in *)&from)->sin_port); - break; -#ifdef INET6 - case AF_INET6: - aport = ntohs(((struct sockaddr_in6 *)&from)->sin6_port); - break; -#endif - default: - aport = 0; /* error */ - break; - } - /* - * XXX careful for ftp bounce attacks. If discovered, shut them - * down and check for the real auxiliary channel to connect. - */ - if (aport == 20) { - close(s3); - goto again; - } - (void)close(s2); - if (s3 < 0) { - (void)fprintf(stderr, - "rcmd: accept: %s\n", strerror(errno)); - lport = 0; - goto bad; - } - *fd2p = s3; - if (aport >= IPPORT_RESERVED || aport < IPPORT_RESERVED / 2) { - (void)fprintf(stderr, - "socket: protocol failure in circuit setup.\n"); - goto bad2; - } - } - (void)write(s, locuser, strlen(locuser)+1); - (void)write(s, remuser, strlen(remuser)+1); - (void)write(s, cmd, strlen(cmd)+1); - if (read(s, &c, 1) != 1) { - (void)fprintf(stderr, - "rcmd: %s: %s\n", *ahost, strerror(errno)); - goto bad2; - } - if (c != 0) { - while (read(s, &c, 1) == 1) { - (void)write(STDERR_FILENO, &c, 1); - if (c == '\n') - break; - } - goto bad2; - } - sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); - cygwin_freeaddrinfo(res); - return (s); -bad2: - if (lport) - (void)close(*fd2p); -bad: - (void)close(s); - sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); - cygwin_freeaddrinfo(res); - return (-1); -} - -extern "C" int -cygwin_rcmd(char **ahost, in_port_t rport, const char *locuser, - const char *remuser, const char *cmd, int *fd2p) -{ - return cygwin_rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, - AF_INET); -} - -extern "C" int -cygwin_rresvport_af(int *alport, int family) -{ - int s; - struct sockaddr_storage ss; - u_short *sport; - - memset(&ss, 0, sizeof(ss)); - ss.ss_family = family; - switch (family) { - case AF_INET: - sport = &((struct sockaddr_in *)&ss)->sin_port; - ((struct sockaddr_in *)&ss)->sin_addr.s_addr = INADDR_ANY; - break; -#ifdef INET6 - case AF_INET6: - sport = &((struct sockaddr_in6 *)&ss)->sin6_port; - ((struct sockaddr_in6 *)&ss)->sin6_addr = in6addr_any; - break; -#endif - default: - errno = EAFNOSUPPORT; - return -1; - } - - s = cygwin_socket(ss.ss_family, SOCK_STREAM, 0); - if (s < 0) - return (-1); -#if 0 /* compat_exact_traditional_rresvport_semantics */ - sin.sin_port = htons((u_short)*alport); - if (_bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) - return (s); - if (errno != EADDRINUSE) { - (void)_close(s); - return (-1); - } -#endif - *sport = 0; - if (cygwin_bindresvport_sa(s, (struct sockaddr *)&ss) == -1) { - (void)close(s); - return (-1); - } - *alport = (int)ntohs(*sport); - return (s); -} - -extern "C" int -cygwin_rresvport(int *port) -{ - return cygwin_rresvport_af(port, AF_INET); -} - -int __check_rhosts_file = 1; -char *__rcmd_errstr; - -/* - * AF independent extension of iruserok. - * - * Returns 0 if ok, -1 if not ok. - */ -extern "C" int -iruserok_sa(const void *ra, int rlen, int superuser, const char *ruser, - const char *luser) -{ - const char *cp; - struct __stat64 sbuf; - struct passwd *pwd; - FILE *hostf; - uid_t uid; - int first; - char pbuf[MAXPATHLEN]; - const struct sockaddr *raddr; - struct sockaddr_storage ss; - - /* avoid alignment issue */ - if (rlen > (int) sizeof(ss)) - return(-1); - memcpy(&ss, ra, rlen); - raddr = (struct sockaddr *)&ss; - - first = 1; - hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "rt"); -again: - if (hostf) { - if (__ivaliduser_sa(hostf, raddr, rlen, luser, ruser) == 0) { - (void)fclose(hostf); - return (0); - } - (void)fclose(hostf); - } - if (first == 1 && (__check_rhosts_file || superuser)) { - first = 0; - if ((pwd = getpwnam(luser)) == NULL) - return (-1); - (void)strcpy(pbuf, pwd->pw_dir); - (void)strcat(pbuf, "/.rhosts"); - - /* - * Change effective uid while opening .rhosts. If root and - * reading an NFS mounted file system, can't read files that - * are protected read/write owner only. - */ - uid = geteuid32(); - (void)seteuid32(pwd->pw_uid); - hostf = fopen(pbuf, "rt"); - (void)seteuid32(uid); - - if (hostf == NULL) - return (-1); - /* - * If not a regular file, or is owned by someone other than - * user or root or if writeable by anyone but the owner, quit. - */ - cp = NULL; - if (lstat64(pbuf, &sbuf) < 0) - cp = ".rhosts lstat failed"; - else if (!S_ISREG(sbuf.st_mode)) - cp = ".rhosts not regular file"; - else if (fstat64(fileno(hostf), &sbuf) < 0) - cp = ".rhosts fstat failed"; - else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) - cp = "bad .rhosts owner"; - else if (sbuf.st_mode & (S_IWGRP|S_IWOTH)) - cp = ".rhosts writeable by other than owner"; - /* If there were any problems, quit. */ - if (cp) { - __rcmd_errstr = (char *) cp; - (void)fclose(hostf); - return (-1); - } - goto again; - } - return (-1); -} - -/* - * New .rhosts strategy: We are passed an ip address. We spin through - * hosts.equiv and .rhosts looking for a match. When the .rhosts only - * has ip addresses, we don't have to trust a nameserver. When it - * contains hostnames, we spin through the list of addresses the nameserver - * gives us and look for a match. - * - * Returns 0 if ok, -1 if not ok. - */ -extern "C" int -iruserok(unsigned long raddr, int superuser, const char *ruser, - const char *luser) -{ - struct sockaddr_in sin; - - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - memcpy(&sin.sin_addr, &raddr, sizeof(sin.sin_addr)); - return iruserok_sa((struct sockaddr *)&sin, sizeof(struct sockaddr_in), - superuser, ruser, luser); -} - -extern "C" int -ruserok(const char *rhost, int superuser, const char *ruser, const char *luser) -{ - struct addrinfo hints, *res, *r; - int error; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; /*dummy*/ - error = cygwin_getaddrinfo(rhost, "0", &hints, &res); - if (error) - return (-1); - - for (r = res; r; r = r->ai_next) { - if (iruserok_sa(r->ai_addr, r->ai_addrlen, superuser, ruser, - luser) == 0) { - cygwin_freeaddrinfo(res); - return (0); - } - } - cygwin_freeaddrinfo(res); - return (-1); -} - -#ifndef __CYGWIN__ -/* - * XXX - * Don't make static, used by lpd(8). - * - * Returns 0 if ok, -1 if not ok. - */ -static int -__ivaliduser(FILE *hostf, u_int32_t raddr, const char *luser, const char *ruser) -{ - struct sockaddr_in sin; - - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - memcpy(&sin.sin_addr, &raddr, sizeof(sin.sin_addr)); - return __ivaliduser_sa(hostf, (struct sockaddr *)&sin, - sizeof(struct sockaddr_in), luser, ruser); -} - -/* - * Returns 0 if ok, -1 if not ok. - * - * XXX obsolete API. - */ -static int -__ivaliduser_af(FILE *hostf, const void *raddr, const char *luser, - const char *ruser, int af, int len) -{ - struct sockaddr *sa = NULL; - struct sockaddr_in *sin = NULL; -#ifdef INET6 - struct sockaddr_in6 *sin6 = NULL; -#endif - struct sockaddr_storage ss; - int salen = 0; - - memset(&ss, 0, sizeof(ss)); - switch (af) { - case AF_INET: - if (len != sizeof(sin->sin_addr)) - return -1; - sin = (struct sockaddr_in *)&ss; - sin->sin_family = AF_INET; - salen = sizeof(struct sockaddr_in); - memcpy(&sin->sin_addr, raddr, sizeof(sin->sin_addr)); - break; -#ifdef INET6 - case AF_INET6: - if (len != sizeof(sin6->sin6_addr)) - return -1; - /* you will lose scope info */ - sin6 = (struct sockaddr_in6 *)&ss; - sin6->sin6_family = AF_INET6; - salen = sizeof(struct sockaddr_in6); - memcpy(&sin6->sin6_addr, raddr, sizeof(sin6->sin6_addr)); - break; -#endif - default: - return -1; - } - - sa = (struct sockaddr *)&ss; - return __ivaliduser_sa(hostf, sa, salen, luser, ruser); -} -#endif - -static int -__ivaliduser_sa(FILE *hostf, const struct sockaddr *raddr, socklen_t salen, - const char *luser, const char *ruser) -{ - char *user, *p; - int ch; - char buf[MAXHOSTNAMELEN + 128]; /* host + login */ - char hname[MAXHOSTNAMELEN]; - /* Presumed guilty until proven innocent. */ - int userok = 0, hostok = 0; -#ifdef YP - char *ypdomain; - - if (yp_get_default_domain(&ypdomain)) - ypdomain = NULL; -#else -#define ypdomain NULL -#endif - /* We need to get the damn hostname back for netgroup matching. */ - if (cygwin_getnameinfo(raddr, salen, hname, sizeof(hname), NULL, 0, - NI_NAMEREQD) != 0) - hname[0] = '\0'; - - while (fgets(buf, sizeof(buf), hostf)) { - p = buf; - /* Skip lines that are too long. */ - if (strchr(p, '\n') == NULL) { - while ((ch = getc(hostf)) != '\n' && ch != EOF); - continue; - } - if (*p == '\n' || *p == '#') { - /* comment... */ - continue; - } - while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') { - *p = isupper((unsigned char)*p) ? tolower((unsigned char)*p) : *p; - p++; - } - if (*p == ' ' || *p == '\t') { - *p++ = '\0'; - while (*p == ' ' || *p == '\t') - p++; - user = p; - while (*p != '\n' && *p != ' ' && - *p != '\t' && *p != '\0') - p++; - } else - user = p; - *p = '\0'; - /* - * Do +/- and +@/-@ checking. This looks really nasty, - * but it matches SunOS's behavior so far as I can tell. - */ - switch(buf[0]) { - case '+': - if (!buf[1]) { /* '+' matches all hosts */ - hostok = 1; - break; - } - if (buf[1] == '@') /* match a host by netgroup */ - hostok = hname[0] != '\0' && - innetgr(&buf[2], hname, NULL, ypdomain); - else /* match a host by addr */ - hostok = __icheckhost(raddr, salen, - (char *)&buf[1]); - break; - case '-': /* reject '-' hosts and all their users */ - if (buf[1] == '@') { - if (hname[0] == '\0' || - innetgr(&buf[2], hname, NULL, ypdomain)) - return(-1); - } else { - if (__icheckhost(raddr, salen, - (char *)&buf[1])) - return(-1); - } - break; - default: /* if no '+' or '-', do a simple match */ - hostok = __icheckhost(raddr, salen, buf); - break; - } - switch(*user) { - case '+': - if (!*(user+1)) { /* '+' matches all users */ - userok = 1; - break; - } - if (*(user+1) == '@') /* match a user by netgroup */ - userok = innetgr(user+2, NULL, ruser, ypdomain); - else /* match a user by direct specification */ - userok = !(strcmp(ruser, user+1)); - break; - case '-': /* if we matched a hostname, */ - if (hostok) { /* check for user field rejections */ - if (!*(user+1)) - return(-1); - if (*(user+1) == '@') { - if (innetgr(user+2, NULL, - ruser, ypdomain)) - return(-1); - } else { - if (!strcmp(ruser, user+1)) - return(-1); - } - } - break; - default: /* no rejections: try to match the user */ - if (hostok) - userok = !(strcmp(ruser,*user ? user : luser)); - break; - } - if (hostok && userok) - return(0); - } - return (-1); -} - -/* - * Returns "true" if match, 0 if no match. - */ -static int -__icheckhost(const struct sockaddr *raddr, socklen_t salen, const char *lhost) -{ - struct sockaddr_in sin; - struct sockaddr_in6 *sin6; - struct addrinfo hints, *res, *r; - int error; - char h1[NI_MAXHOST], h2[NI_MAXHOST]; - - if (raddr->sa_family == AF_INET6) { - sin6 = (struct sockaddr_in6 *)raddr; - if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - memcpy(&sin.sin_addr, &sin6->sin6_addr.s6_addr[12], - sizeof(sin.sin_addr)); - raddr = (struct sockaddr *)&sin; - salen = sizeof(struct sockaddr_in); - } - } - - h1[0] = '\0'; - if (cygwin_getnameinfo(raddr, salen, h1, sizeof(h1), NULL, 0, - NI_NUMERICHOST) != 0) - return (0); - - /* Resolve laddr into sockaddr */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = raddr->sa_family; - hints.ai_socktype = SOCK_DGRAM; /*XXX dummy*/ - res = NULL; - error = cygwin_getaddrinfo(lhost, "0", &hints, &res); - if (error) - return (0); - - for (r = res; r ; r = r->ai_next) { - h2[0] = '\0'; - if (cygwin_getnameinfo(r->ai_addr, r->ai_addrlen, h2, sizeof(h2), - NULL, 0, NI_NUMERICHOST) != 0) - continue; - if (strcmp(h1, h2) == 0) { - cygwin_freeaddrinfo(res); - return (1); - } - } - - /* No match. */ - cygwin_freeaddrinfo(res); - return (0); -} diff --git a/winsup/cygwin/libc/rexec.cc b/winsup/cygwin/libc/rexec.cc deleted file mode 100644 index 99d76f68c..000000000 --- a/winsup/cygwin/libc/rexec.cc +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Copyright (c) 1980, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* CV 2006-07-04: Tweaked for inclusion into Cygwin. */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rexec.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - -#ifdef __CYGWIN__ -#include "winsup.h" -#include "sigproc.h" -#include "cygtls.h" -#include <wininet.h> -#endif - -#include <sys/types.h> -#include <sys/uio.h> -#include <sys/socket.h> -#include <sys/param.h> -#include <sys/stat.h> - -#include <netinet/in.h> - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <netdb.h> -#include <errno.h> -#include <ctype.h> -#include <err.h> -#include <stdlib.h> -#include <unistd.h> - -extern "C" { - int cygwin_accept (int, struct sockaddr *, socklen_t *); - int cygwin_connect (int, const struct sockaddr *, socklen_t); - int cygwin_getsockname (int, struct sockaddr *, socklen_t *); - void cygwin_herror (const char *); - int cygwin_listen (int, int); - int cygwin_socket (int, int, int); -} - -/* - * Options and other state info. - */ -struct macel { - char mac_name[9]; /* macro name */ - char *mac_start; /* start of macro in macbuf */ - char *mac_end; /* end of macro in macbuf */ -}; - -int macnum; /* number of defined macros */ -struct macel macros[16]; -char macbuf[4096]; - -static FILE *cfile; - -#define DEFAULT 1 -#define LOGIN 2 -#define PASSWD 3 -#define ACCOUNT 4 -#define MACDEF 5 -#define ID 10 -#define MACH 11 - -static char tokval[100]; - -static struct toktab { - const char *tokstr; - int tval; -} toktab[]= { - { "default", DEFAULT }, - { "login", LOGIN }, - { "password", PASSWD }, - { "passwd", PASSWD }, - { "account", ACCOUNT }, - { "machine", MACH }, - { "macdef", MACDEF }, - { NULL, 0 } -}; - -static int -token() -{ - char *cp; - int c; - struct toktab *t; - - if (feof(cfile) || ferror(cfile)) - return (0); - while ((c = getc(cfile)) != EOF && - (c == '\n' || c == '\t' || c == ' ' || c == ',')) - continue; - if (c == EOF) - return (0); - cp = tokval; - if (c == '"') { - while ((c = getc(cfile)) != EOF && c != '"') { - if (c == '\\') - c = getc(cfile); - *cp++ = c; - } - } else { - *cp++ = c; - while ((c = getc(cfile)) != EOF - && c != '\n' && c != '\t' && c != ' ' && c != ',') { - if (c == '\\') - c = getc(cfile); - *cp++ = c; - } - } - *cp = 0; - if (tokval[0] == 0) - return (0); - for (t = toktab; t->tokstr; t++) - if (!strcmp(t->tokstr, tokval)) - return (t->tval); - return (ID); -} - -static int -ruserpass(const char *host, char **aname, char **apass, char **aacct) -{ - const char *hdir; - char buf[BUFSIZ], *tmp; - char myname[INTERNET_MAX_HOST_NAME_LENGTH + 1]; - const char *mydomain; - int t, i, c, usedefault = 0; - struct stat stb; - - hdir = getenv("HOME"); - if (hdir == NULL) - hdir = "."; - if (strlen(hdir) + 8 > sizeof(buf)) - return (0); - (void) sprintf(buf, "%s/.netrc", hdir); - cfile = fopen(buf, "r"); - if (cfile == NULL) { - if (errno != ENOENT) - warn("%s", buf); - return (0); - } - if (cygwin_gethostname(myname, sizeof(myname)) < 0) - myname[0] = '\0'; - if ((mydomain = strchr(myname, '.')) == NULL) - mydomain = ""; -next: - while ((t = token())) switch(t) { - - case DEFAULT: - usedefault = 1; - /* FALL THROUGH */ - - case MACH: - if (!usedefault) { - if (token() != ID) - continue; - /* - * Allow match either for user's input host name - * or official hostname. Also allow match of - * incompletely-specified host in local domain. - */ - if (strcasecmp(host, tokval) == 0) - goto match; - if ((tmp = strchr(host, '.')) != NULL && - strcasecmp(tmp, mydomain) == 0 && - strncasecmp(host, tokval, tmp - host) == 0 && - tokval[tmp - host] == '\0') - goto match; - continue; - } - match: - while ((t = token()) && t != MACH && t != DEFAULT) switch(t) { - - case LOGIN: - if (token()) - if (*aname == 0) { - *aname = (char *) malloc((unsigned) strlen(tokval) + 1); - (void) strcpy(*aname, tokval); - } else { - if (strcmp(*aname, tokval)) - goto next; - } - break; - case PASSWD: - if ((*aname == 0 || strcmp(*aname, "anonymous")) && - fstat(fileno(cfile), &stb) >= 0 && - (stb.st_mode & 077) != 0) { - warnx("Error: .netrc file is readable by others."); - warnx("Remove password or make file unreadable by others."); - goto bad; - } - if (token() && *apass == 0) { - *apass = (char *) malloc((unsigned) strlen(tokval) + 1); - (void) strcpy(*apass, tokval); - } - break; - case ACCOUNT: - if (fstat(fileno(cfile), &stb) >= 0 - && (stb.st_mode & 077) != 0) { - warnx("Error: .netrc file is readable by others."); - warnx("Remove account or make file unreadable by others."); - goto bad; - } - if (token() && aacct && *aacct == 0) { - *aacct = (char *) malloc((unsigned) strlen(tokval) + 1); - (void) strcpy(*aacct, tokval); - } - break; - case MACDEF: - while ((c=getc(cfile)) != EOF && - (c == ' ' || c == '\t')) - ; - if (c == EOF || c == '\n') { - printf("Missing macdef name argument.\n"); - goto bad; - } - if (macnum == 16) { - printf("Limit of 16 macros have already been defined\n"); - goto bad; - } - tmp = macros[macnum].mac_name; - *tmp++ = c; - for (i=0; i < 8 && (c=getc(cfile)) != EOF && - !isspace(c); ++i) { - *tmp++ = c; - } - if (c == EOF) { - printf("Macro definition missing null line terminator.\n"); - goto bad; - } - *tmp = '\0'; - if (c != '\n') { - while ((c=getc(cfile)) != EOF && c != '\n'); - } - if (c == EOF) { - printf("Macro definition missing null line terminator.\n"); - goto bad; - } - if (macnum == 0) { - macros[macnum].mac_start = macbuf; - } - else { - macros[macnum].mac_start = macros[macnum-1].mac_end + 1; - } - tmp = macros[macnum].mac_start; - while (tmp != macbuf + 4096) { - if ((c=getc(cfile)) == EOF) { - printf("Macro definition missing null line terminator.\n"); - goto bad; - } - *tmp = c; - if (*tmp == '\n') { - if (*(tmp-1) == '\0') { - macros[macnum++].mac_end = tmp - 1; - break; - } - *tmp = '\0'; - } - tmp++; - } - if (tmp == macbuf + 4096) { - printf("4K macro buffer exceeded\n"); - goto bad; - } - break; - default: - warnx("Unknown .netrc keyword %s", tokval); - break; - } - goto done; - } -done: - (void) fclose(cfile); - return (0); -bad: - (void) fclose(cfile); - return (-1); -} - -extern "C" int -cygwin_rexec (char **ahost, unsigned short rport, char *name, char *pass, - char *cmd, int *fd2p) -{ - struct sockaddr_in sin, sin2, from; - struct hostent *hp; - u_short port = 0; - int s, timo = 1, s3; - char c; - char ahostbuf[INTERNET_MAX_HOST_NAME_LENGTH + 1]; - - sig_dispatch_pending (); - myfault efault; - if (efault.faulted (EFAULT)) - return -1; - - hp = cygwin_gethostbyname(*ahost); - if (hp == 0) { - cygwin_herror(*ahost); - return (-1); - } - *ahost = strcpy (ahostbuf, hp->h_name); - ruserpass(hp->h_name, &name, &pass, NULL); - if (!name) - name = getlogin (); - if (!pass) - pass = almost_null; -retry: - s = cygwin_socket(AF_INET, SOCK_STREAM, 0); - if (s < 0) { - perror("rexec: socket"); - return (-1); - } - sin.sin_family = hp->h_addrtype; - sin.sin_port = rport; - bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); - if (cygwin_connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { - if (errno == ECONNREFUSED && timo <= 16) { - (void) close(s); - sleep(timo); - timo *= 2; - goto retry; - } - perror(hp->h_name); - return (-1); - } - if (fd2p == 0) { - (void) write(s, "", 1); - } else { - char num[8]; - int s2, sin2len; - - s2 = cygwin_socket(AF_INET, SOCK_STREAM, 0); - if (s2 < 0) { - (void) close(s); - return (-1); - } - cygwin_listen(s2, 1); - sin2len = sizeof (sin2); - if (cygwin_getsockname(s2, (struct sockaddr *)&sin2, &sin2len) < 0 || - sin2len != sizeof (sin2)) { - perror("getsockname"); - (void) close(s2); - goto bad; - } - port = ntohs((u_short)sin2.sin_port); - (void) sprintf(num, "%u", port); - (void) write(s, num, strlen(num)+1); - { int len = sizeof (from); - s3 = cygwin_accept(s2, (struct sockaddr *)&from, &len); - close(s2); - if (s3 < 0) { - perror("accept"); - port = 0; - goto bad; - } - } - *fd2p = s3; - } - (void) write(s, name, strlen(name) + 1); - /* should public key encypt the password here */ - (void) write(s, pass, strlen(pass) + 1); - (void) write(s, cmd, strlen(cmd) + 1); - if (read(s, &c, 1) != 1) { - perror(*ahost); - goto bad; - } - if (c != 0) { - while (read(s, &c, 1) == 1) { - (void) write(2, &c, 1); - if (c == '\n') - break; - } - goto bad; - } - return (s); -bad: - if (port) - (void) close(*fd2p); - (void) close(s); - return (-1); -} diff --git a/winsup/cygwin/libc/strptime.cc b/winsup/cygwin/libc/strptime.cc deleted file mode 100644 index e81cdd580..000000000 --- a/winsup/cygwin/libc/strptime.cc +++ /dev/null @@ -1,545 +0,0 @@ -/* - * Powerdog Industries kindly requests feedback from anyone modifying - * this function: - * - * Date: Thu, 05 Jun 1997 23:17:17 -0400 - * From: Kevin Ruddy <kevin.ruddy@powerdog.com> - * To: James FitzGibbon <james@nexis.net> - * Subject: Re: Use of your strptime(3) code (fwd) - * - * The reason for the "no mod" clause was so that modifications would - * come back and we could integrate them and reissue so that a wider - * audience could use it (thereby spreading the wealth). This has - * made it possible to get strptime to work on many operating systems. - * I'm not sure why that's "plain unacceptable" to the FreeBSD team. - * - * Anyway, you can change it to "with or without modification" as - * you see fit. Enjoy. - * - * Kevin Ruddy - * Powerdog Industries, Inc. - */ -/* - * Copyright (c) 1994 Powerdog Industries. 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 Powerdog Industries. - * 4. The name of Powerdog Industries may not be used to endorse or - * promote products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``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 POWERDOG INDUSTRIES 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> -#ifdef __CYGWIN__ -#include "winsup.h" -#else -#ifndef lint -#ifndef NOID -static char copyright[] __unused = -"@(#) Copyright (c) 1994 Powerdog Industries. All rights reserved."; -static char sccsid[] __unused = "@(#)strptime.c 0.1 (Powerdog) 94/03/27"; -#endif /* !defined NOID */ -#endif /* not lint */ -__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/stdtime/strptime.c,v 1.35 2003/11/17 04:19:15 nectar Exp $"); - -#include "namespace.h" -#endif -#include <time.h> -#include <ctype.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#ifndef __CYGWIN__ -#include <pthread.h> -#include "un-namespace.h" -#include "libc_private.h" -#endif -#include "timelocal.h" - -static char * _strptime(const char *, const char *, struct tm *, int *); - -#define asizeof(a) ((int)(sizeof (a) / sizeof ((a)[0]))) - -static char * -_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp) -{ - char c; - const char *ptr; - int i, - len; - int Ealternative, Oalternative; - struct lc_time_T *tptr = __get_current_time_locale(); - - ptr = fmt; - while (*ptr != 0) { - if (*buf == 0) - break; - - c = *ptr++; - - if (c != '%') { - if (isspace((unsigned char)c)) - while (*buf != 0 && isspace((unsigned char)*buf)) - buf++; - else if (c != *buf++) - return 0; - continue; - } - - Ealternative = 0; - Oalternative = 0; -label: - c = *ptr++; - switch (c) { - case 0: - case '%': - if (*buf++ != '%') - return 0; - break; - - case '+': - buf = _strptime(buf, tptr->date_fmt, tm, GMTp); - if (buf == 0) - return 0; - break; - - case 'C': - if (!isdigit((unsigned char)*buf)) - return 0; - - /* XXX This will break for 3-digit centuries. */ - len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (i < 19) - return 0; - - tm->tm_year = i * 100 - 1900; - break; - - case 'c': - buf = _strptime(buf, tptr->c_fmt, tm, GMTp); - if (buf == 0) - return 0; - break; - - case 'D': - buf = _strptime(buf, "%m/%d/%y", tm, GMTp); - if (buf == 0) - return 0; - break; - - case 'E': - if (Ealternative || Oalternative) - break; - Ealternative++; - goto label; - - case 'O': - if (Ealternative || Oalternative) - break; - Oalternative++; - goto label; - - case 'F': - buf = _strptime(buf, "%Y-%m-%d", tm, GMTp); - if (buf == 0) - return 0; - break; - - case 'R': - buf = _strptime(buf, "%H:%M", tm, GMTp); - if (buf == 0) - return 0; - break; - - case 'r': - buf = _strptime(buf, tptr->ampm_fmt, tm, GMTp); - if (buf == 0) - return 0; - break; - - case 'T': - buf = _strptime(buf, "%H:%M:%S", tm, GMTp); - if (buf == 0) - return 0; - break; - - case 'X': - buf = _strptime(buf, tptr->X_fmt, tm, GMTp); - if (buf == 0) - return 0; - break; - - case 'x': - buf = _strptime(buf, tptr->x_fmt, tm, GMTp); - if (buf == 0) - return 0; - break; - - case 'j': - if (!isdigit((unsigned char)*buf)) - return 0; - - len = 3; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (i < 1 || i > 366) - return 0; - - tm->tm_yday = i - 1; - break; - - case 'M': - case 'S': - if (*buf == 0 || isspace((unsigned char)*buf)) - break; - - if (!isdigit((unsigned char)*buf)) - return 0; - - len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - - if (c == 'M') { - if (i > 59) - return 0; - tm->tm_min = i; - } else { - if (i > 60) - return 0; - tm->tm_sec = i; - } - - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) - ptr++; - break; - - case 'H': - case 'I': - case 'k': - case 'l': - /* - * Of these, %l is the only specifier explicitly - * documented as not being zero-padded. However, - * there is no harm in allowing zero-padding. - * - * XXX The %l specifier may gobble one too many - * digits if used incorrectly. - */ - if (!isdigit((unsigned char)*buf)) - return 0; - - len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (c == 'H' || c == 'k') { - if (i > 23) - return 0; - } else if (i > 12) - return 0; - - tm->tm_hour = i; - - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) - ptr++; - break; - - case 'p': - /* - * XXX This is bogus if parsed before hour-related - * specifiers. - */ - len = strlen(tptr->am); - if (strncasecmp(buf, tptr->am, len) == 0) { - if (tm->tm_hour > 12) - return 0; - if (tm->tm_hour == 12) - tm->tm_hour = 0; - buf += len; - break; - } - - len = strlen(tptr->pm); - if (strncasecmp(buf, tptr->pm, len) == 0) { - if (tm->tm_hour > 12) - return 0; - if (tm->tm_hour != 12) - tm->tm_hour += 12; - buf += len; - break; - } - - return 0; - - case 'A': - case 'a': - len = 0; - for (i = 0; i < asizeof(tptr->weekday); i++) { - len = strlen(tptr->weekday[i]); - if (strncasecmp(buf, tptr->weekday[i], - len) == 0) - break; - len = strlen(tptr->wday[i]); - if (strncasecmp(buf, tptr->wday[i], - len) == 0) - break; - } - if (i == asizeof(tptr->weekday)) - return 0; - - tm->tm_wday = i; - buf += len; - break; - - case 'U': - case 'W': - /* - * XXX This is bogus, as we can not assume any valid - * information present in the tm structure at this - * point to calculate a real value, so just check the - * range for now. - */ - if (!isdigit((unsigned char)*buf)) - return 0; - - len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (i > 53) - return 0; - - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) - ptr++; - break; - - case 'w': - if (!isdigit((unsigned char)*buf)) - return 0; - - i = *buf - '0'; - if (i > 6) - return 0; - - tm->tm_wday = i; - - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) - ptr++; - break; - - case 'd': - case 'e': - /* - * The %e specifier is explicitly documented as not - * being zero-padded but there is no harm in allowing - * such padding. - * - * XXX The %e specifier may gobble one too many - * digits if used incorrectly. - */ - if (!isdigit((unsigned char)*buf)) - return 0; - - len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (i > 31) - return 0; - - tm->tm_mday = i; - - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) - ptr++; - break; - - case 'B': - case 'b': - case 'h': - len = 0; - for (i = 0; i < asizeof(tptr->month); i++) { - if (Oalternative) { - if (c == 'B') { - len = strlen(tptr->alt_month[i]); - if (strncasecmp(buf, - tptr->alt_month[i], - len) == 0) - break; - } - } else { - len = strlen(tptr->month[i]); - if (strncasecmp(buf, tptr->month[i], - len) == 0) - break; - len = strlen(tptr->mon[i]); - if (strncasecmp(buf, tptr->mon[i], - len) == 0) - break; - } - } - if (i == asizeof(tptr->month)) - return 0; - - tm->tm_mon = i; - buf += len; - break; - - case 'm': - if (!isdigit((unsigned char)*buf)) - return 0; - - len = 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (i < 1 || i > 12) - return 0; - - tm->tm_mon = i - 1; - - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) - ptr++; - break; - - case 's': - { - char *cp; - int sverrno; - long n; - time_t t; - - sverrno = errno; - errno = 0; - n = strtol(buf, &cp, 10); - if (errno == ERANGE || (long)(t = n) != n) { - errno = sverrno; - return 0; - } - errno = sverrno; - buf = cp; - gmtime_r(&t, tm); - *GMTp = 1; - } - break; - - case 'Y': - case 'y': - if (*buf == 0 || isspace((unsigned char)*buf)) - break; - - if (!isdigit((unsigned char)*buf)) - return 0; - - len = (c == 'Y') ? 4 : 2; - for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) { - i *= 10; - i += *buf - '0'; - len--; - } - if (c == 'Y') - i -= 1900; - if (c == 'y' && i < 69) - i += 100; - if (i < 0) - return 0; - - tm->tm_year = i; - - if (*buf != 0 && isspace((unsigned char)*buf)) - while (*ptr != 0 && !isspace((unsigned char)*ptr)) - ptr++; - break; - - case 'Z': - { - const char *cp; - char *zonestr; - - for (cp = buf; *cp && isupper((unsigned char)*cp); ++cp) {/*empty*/} - if (cp - buf) { - zonestr = (char *) alloca(cp - buf + 1); - strncpy(zonestr, buf, cp - buf); - zonestr[cp - buf] = '\0'; - tzset(); - if (0 == strcmp(zonestr, "GMT")) { - *GMTp = 1; - } else if (0 == strcmp(zonestr, tzname[0])) { - tm->tm_isdst = 0; - } else if (0 == strcmp(zonestr, tzname[1])) { - tm->tm_isdst = 1; - } else { - return 0; - } - buf += cp - buf; - } - } - break; - } - } - return (char *)buf; -} - -extern "C" char * -strptime(const char * __restrict buf, const char * __restrict fmt, - struct tm * __restrict tm) -{ - char *ret; - int gmt; - - gmt = 0; - ret = _strptime(buf, fmt, tm, &gmt); - if (ret && gmt) { - time_t t = timegm(tm); - localtime_r(&t, tm); - } - - return (ret); -} diff --git a/winsup/cygwin/libc/timelocal.cc b/winsup/cygwin/libc/timelocal.cc deleted file mode 100644 index 59a2e4155..000000000 --- a/winsup/cygwin/libc/timelocal.cc +++ /dev/null @@ -1,125 +0,0 @@ -/*- - * Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org> - * Copyright (c) 1997 FreeBSD Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -//__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/stdtime/timelocal.c,v 1.25 2003/06/13 00:14:07 jkh Exp $"); - -#include <stddef.h> - -//#include "ldpart.h" -#include "timelocal.h" - -#ifndef __CYGWIN__ -static struct lc_time_T _time_locale; -static int _time_using_locale; -static char *time_locale_buf; -#endif - -#define LCTIME_SIZE (sizeof(struct lc_time_T) / sizeof(char *)) - -static const struct lc_time_T _C_time_locale = { - { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }, { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" - }, { - "Sun", "Mon", "Tue", "Wed", - "Thu", "Fri", "Sat" - }, { - "Sunday", "Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday" - }, - - /* X_fmt */ - "%H:%M:%S", - - /* - * x_fmt - * Since the C language standard calls for - * "date, using locale's date format," anything goes. - * Using just numbers (as here) makes Quakers happier; - * it's also compatible with SVR4. - */ - "%m/%d/%y", - - /* - * c_fmt - */ - "%a %b %e %H:%M:%S %Y", - - /* am */ - "AM", - - /* pm */ - "PM", - - /* date_fmt */ - "%a %b %e %H:%M:%S %Z %Y", - - /* alt_month - * Standalone months forms for %OB - */ - { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" - }, - - /* md_order - * Month / day order in dates - */ - "md", - - /* ampm_fmt - * To determine 12-hour clock format time (empty, if N/A) - */ - "%I:%M:%S %p" -}; - -extern "C" struct lc_time_T * -__get_current_time_locale(void) -{ -#ifdef __CYGWIN__ - return (struct lc_time_T *)&_C_time_locale; -#else - return (_time_using_locale - ? &_time_locale - : (struct lc_time_T *)&_C_time_locale); -#endif -} - -#ifndef __CYGWIN__ -extern "C" int -__time_load_locale(const char *name) -{ - return (__part_load_locale(name, &_time_using_locale, - &time_locale_buf, "LC_TIME", - LCTIME_SIZE, LCTIME_SIZE, - (const char **)&_time_locale)); -} -#endif diff --git a/winsup/cygwin/libc/timelocal.h b/winsup/cygwin/libc/timelocal.h deleted file mode 100644 index e7d515276..000000000 --- a/winsup/cygwin/libc/timelocal.h +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * Copyright (c) 1997-2002 FreeBSD Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: /repoman/r/ncvs/src/lib/libc/stdtime/timelocal.h,v 1.11 2002/01/24 15:07:44 phantom Exp $ - */ - -#ifndef _TIMELOCAL_H_ -#define _TIMELOCAL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Private header file for the strftime and strptime localization - * stuff. - */ -struct lc_time_T { - const char *mon[12]; - const char *month[12]; - const char *wday[7]; - const char *weekday[7]; - const char *X_fmt; - const char *x_fmt; - const char *c_fmt; - const char *am; - const char *pm; - const char *date_fmt; - const char *alt_month[12]; - const char *md_order; - const char *ampm_fmt; -}; - -struct lc_time_T *__get_current_time_locale(void); -#ifndef __CYGWIN__ -int __time_load_locale(const char *); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* !_TIMELOCAL_H_ */ |