diff options
Diffstat (limited to 'winsup/cygwin/libc')
-rw-r--r-- | winsup/cygwin/libc/bsdlib.cc | 303 | ||||
-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 | 107 | ||||
-rw-r--r-- | winsup/cygwin/libc/getopt.c | 522 | ||||
-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/minires-os-if.c | 568 | ||||
-rw-r--r-- | winsup/cygwin/libc/minires.c | 904 | ||||
-rw-r--r-- | winsup/cygwin/libc/minires.h | 68 | ||||
-rw-r--r-- | winsup/cygwin/libc/nftw.c | 126 | ||||
-rw-r--r-- | winsup/cygwin/libc/rcmd.cc | 782 | ||||
-rw-r--r-- | winsup/cygwin/libc/rexec.cc | 416 | ||||
-rw-r--r-- | winsup/cygwin/libc/strptime.cc | 428 | ||||
-rw-r--r-- | winsup/cygwin/libc/xsique.cc | 48 |
15 files changed, 0 insertions, 6097 deletions
diff --git a/winsup/cygwin/libc/bsdlib.cc b/winsup/cygwin/libc/bsdlib.cc deleted file mode 100644 index 9d488c35a..000000000 --- a/winsup/cygwin/libc/bsdlib.cc +++ /dev/null @@ -1,303 +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: - 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[TTY_NAME_MAX]; - - 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 (const struct utmp *ut) -{ - pututline (ut); - endutent (); - updwtmp (_PATH_WTMP, ut); -} - -extern "C" int -logout (const 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 9863e1621..000000000 --- a/winsup/cygwin/libc/ftw.c +++ /dev/null @@ -1,107 +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; - -#if 0 - /* GLibc allows nfds < 1 and treats it as nfds == 1. Since nfds is - not used in this OpenBSD version anyway, just ignore it for - Linux compatibility. */ - /* XXX - nfds is currently unused */ - if (nfds < 1 || nfds > OPEN_MAX) { - errno = EINVAL; - return (-1); - } -#endif - - 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 0b5a18025..000000000 --- a/winsup/cygwin/libc/getopt.c +++ /dev/null @@ -1,522 +0,0 @@ -/* $OpenBSD: getopt_long.c,v 1.23 2007/10/31 12:34:57 chl 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. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <err.h> -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#define __INSIDE_CYGWIN__ -#include <getopt.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; - 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]; - } - 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 don't 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(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(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/minires-os-if.c b/winsup/cygwin/libc/minires-os-if.c deleted file mode 100644 index 1908ccf62..000000000 --- a/winsup/cygwin/libc/minires-os-if.c +++ /dev/null @@ -1,568 +0,0 @@ -/* minires-os-if.c. Stub synchronous resolver for Cygwin. - - Copyright 2006, 2007 Red Hat, Inc. - - Written by Pierre A. Humblet <Pierre.Humblet@ieee.org> - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#include "minires.h" - -#ifdef __CYGWIN__ -/*********************************************************************** - * - Windows interface code - -***********************************************************************/ - -/* Conflict between Windows definitions and others */ -#undef ERROR -#undef NOERROR -#undef DELETE - -#include <windows.h> -#include <iphlpapi.h> -#include <windns.h> -#include <sys/cygwin.h> - -/*********************************************************************** - * write_record: Translates a Windows DNS record into a compressed record - ***********************************************************************/ - -#define PUTDOMAIN(d,p)\ - {int res = dn_comp(d, p, EndPtr - p, dnptrs, lastdnptr); p += res < 0 ? strlen(d) : res; } - -static u_char * write_record(unsigned char * ptr, PDNS_RECORD rr, unsigned char * EndPtr, - unsigned char ** dnptrs, unsigned char ** lastdnptr, int debug) -{ - u_char * rd_length_ptr; - - PUTDOMAIN(rr->pName, ptr); - - if (ptr + 4 > EndPtr) - ptr += 4; - else { - PUTSHORT(rr->wType, ptr); - PUTSHORT(ns_c_in, ptr); - } - if ((rr->Flags.DW & 0x3) == DnsSectionQuestion) - return ptr; - - if (ptr + 4 > EndPtr) - ptr += 4; - else { - PUTLONG(rr->dwTtl, ptr); - } - rd_length_ptr = ptr; - ptr += 2; /* Placeholder for RDLENGTH */ - - /* The default case uses an undocumented feature of the Windows - resolver for types greater than 16. - The DNS_RECORD Data contains the record in wire format. */ - - switch(rr->wType) { - case DNS_TYPE_A: - { - u_char * aptr = (u_char *) & rr->Data.A.IpAddress; - if (ptr + 4 <= EndPtr) { - ptr[0] = aptr[0]; - ptr[1] = aptr[1]; - ptr[2] = aptr[2]; - ptr[3] = aptr[3]; - } - ptr += 4; - break; - } - case DNS_TYPE_NS: - case DNS_TYPE_MD: - case DNS_TYPE_MF: - case DNS_TYPE_CNAME: - case DNS_TYPE_MB: - case DNS_TYPE_MG: - case DNS_TYPE_MR: - case DNS_TYPE_PTR: - PUTDOMAIN(rr->Data.PTR.pNameHost, ptr); - break; - case DNS_TYPE_SOA: - PUTDOMAIN(rr->Data.SOA.pNamePrimaryServer, ptr); - PUTDOMAIN(rr->Data.SOA.pNameAdministrator, ptr); - if (ptr + 20 > EndPtr) - ptr += 20; - else { - PUTLONG(rr->Data.SOA.dwSerialNo, ptr); - PUTLONG(rr->Data.SOA.dwRefresh, ptr); - PUTLONG(rr->Data.SOA.dwRetry, ptr); - PUTLONG(rr->Data.SOA.dwExpire, ptr); - PUTLONG(rr->Data.SOA.dwDefaultTtl, ptr); - } - break; - case DNS_TYPE_NULL: - if (ptr + rr->Data.Null.dwByteCount <= EndPtr) - memcpy(ptr, rr->Data.Null.Data, rr->Data.Null.dwByteCount); - ptr += rr->Data.Null.dwByteCount; - if (rr->Data.Null.dwByteCount == rr->wDataLength - sizeof(DNS_NULL_DATA) + 1) - DPRINTF(debug, "Null byte count has an unexpected value\n"); - break; - case DNS_TYPE_WKS: - if (ptr + rr->wDataLength - sizeof(DNS_WKS_DATA) + 1 + 5 > EndPtr) - ptr += rr->wDataLength - sizeof(DNS_WKS_DATA) + 1 + 5; - else { - PUTLONG(rr->Data.WKS.IpAddress, ptr); - *ptr++ = rr->Data.WKS.chProtocol; - memcpy(ptr, rr->Data.WKS.BitMask, rr->wDataLength - sizeof(DNS_WKS_DATA) + 1); - ptr += rr->wDataLength - sizeof(DNS_WKS_DATA) + 1; - } - break; - case DNS_TYPE_MINFO: - case DNS_TYPE_RP: - PUTDOMAIN(rr->Data.MINFO.pNameMailbox, ptr); - PUTDOMAIN(rr->Data.MINFO.pNameErrorsMailbox, ptr); - break; - case DNS_TYPE_MX: - case DNS_TYPE_AFSDB: - case DNS_TYPE_RT: - if (ptr + 2 > EndPtr) - ptr += 2; - else - PUTSHORT(rr->Data.MX.wPreference, ptr); - PUTDOMAIN(rr->Data.MX.pNameExchange, ptr); - break; - case DNS_TYPE_HINFO: - case DNS_TYPE_ISDN: - case DNS_TYPE_TEXT: - case DNS_TYPE_X25: - { - unsigned int i, len; - for (i = 0; i < rr->Data.TXT.dwStringCount; i++) { - len = strlen(rr->Data.TXT.pStringArray[i]) & 0xFF; - if (ptr + len + 1 > EndPtr) - ptr += len + 1; - else { - *ptr++ = len; - memcpy(ptr, rr->Data.TXT.pStringArray[i], len); - ptr += len; - } - } - break; - } - case DNS_TYPE_SRV: - if (ptr + 6 > EndPtr) - ptr += 6; - else { - PUTSHORT(rr->Data.SRV.wPriority, ptr); - PUTSHORT(rr->Data.SRV.wWeight, ptr); - PUTSHORT(rr->Data.SRV.wPort, ptr); - } - PUTDOMAIN(rr->Data.SRV.pNameTarget, ptr); - break; - default: - { - unsigned int len = rr->wDataLength; - DPRINTF(debug, "No structure for wType %d\n", rr->wType); - if (ptr + len <= EndPtr) - memcpy(ptr, (char *) &rr->Data, len); - ptr += len; - break; - } - } - if (rd_length_ptr + 2 <= EndPtr) - PUTSHORT(ptr - rd_length_ptr - 2, rd_length_ptr); - return ptr; -} - -/*********************************************************************** - * - cygwin_query: implements res_nquery by calling DnsQuery - - ***********************************************************************/ -static int cygwin_query(res_state statp, const char * DomName, int Class, int Type, - unsigned char * AnsPtr, int AnsLength) -{ - DNS_STATUS res; - PDNS_RECORD pQueryResultsSet, rr; - int section, len, counts[4] = {0, 0, 0, 0}, debug = statp->options & RES_DEBUG; - unsigned char * dnptrs[256], * ptr; - - dnptrs[0] = AnsPtr; - dnptrs[1] = NULL; - - if (Class != ns_c_in) { - errno = ENOSYS; - statp->res_h_errno = NETDB_INTERNAL; - return -1; - } - - res = DnsQuery_A(DomName, Type, DNS_QUERY_TREAT_AS_FQDN, - NULL, &pQueryResultsSet, NULL); -#if 0 -#define NETDB_INTERNAL -1 /* see errno */ -#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ -#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */ -#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ -#define NO_DATA 4 /* Valid name, no data record of requested type */ -#endif - - DPRINTF(debug, "DnsQuery: %lu (Windows)\n", res); - if (res) { - switch (res) { - case ERROR_INVALID_NAME: - errno = EINVAL; - statp->res_h_errno = NETDB_INTERNAL;; - break; - case ERROR_TIMEOUT: - statp->res_h_errno = TRY_AGAIN; - break; - case DNS_ERROR_RCODE_NAME_ERROR: - statp->res_h_errno = HOST_NOT_FOUND; - break; - case DNS_ERROR_RCODE_SERVER_FAILURE: - statp->res_h_errno = TRY_AGAIN; - break; - case DNS_ERROR_NO_DNS_SERVERS: - case DNS_ERROR_RCODE_FORMAT_ERROR: - case DNS_ERROR_RCODE_NOT_IMPLEMENTED: - case DNS_ERROR_RCODE_REFUSED: - statp->res_h_errno = NO_RECOVERY; - break; - case DNS_INFO_NO_RECORDS: /* May be returned even if the host doesn't exist */ - statp->res_h_errno = NO_DATA; - break; - default: - DPRINTF(debug, "Unknown code %lu for %s %d\n", res, DomName, Type); - statp->res_h_errno = NO_RECOVERY; - break; - } - len = -1; - goto done; - } - - ptr = AnsPtr + HFIXEDSZ; /* Skip header */ - - rr = pQueryResultsSet; - section = 0; - while (rr) { - if (!counts[0] && (rr->Flags.DW & 0x3)) { - /* No question. Adopt the first name as the name in the question */ - if ((len = dn_comp(rr->pName, ptr, AnsLength - 4, - dnptrs, &dnptrs[DIM(dnptrs) - 1])) < 0) { - ptr = NULL; - break; - } - ptr += len; - PUTSHORT(Type, ptr); - PUTSHORT(ns_c_in, ptr); - counts[0] = 1; - } - - DPRINTF(debug, "%s Section %d Type %u Windows Record Length %u\n", - rr->pName, rr->Flags.DW & 0x3, rr->wType, rr->wDataLength); - - /* Check the records are in correct section order */ - if ((rr->Flags.DW & 0x3) < section) { - DPRINTF(debug, "Unexpected section order %s %d\n", DomName, Type); - continue; - } - section = rr->Flags.DW & 0x3; - - ptr = write_record(ptr, rr, AnsPtr + AnsLength, dnptrs, - &dnptrs[DIM(dnptrs) - 1], debug); - - counts[section]++; - rr = rr->pNext; - } - - DnsRecordListFree(pQueryResultsSet, DnsFreeRecordList); - - len = ptr - AnsPtr; -done: - ptr = AnsPtr; - PUTSHORT(0, ptr); /* Id */ - PUTSHORT((QR << 8) + RA + RD, ptr); - for (section = 0; section < DIM(counts); section++) { - PUTSHORT(counts[section], ptr); - } - return len; -} - -/*********************************************************************** - * - get_registry_items: returns dns items from the registry - - kHey: Handle to registry key - KeyValue: key value to read - what: 0 addresses ; 1 search list - -***********************************************************************/ -static void get_registry_dns_items(HKEY hKey, LPCTSTR KeyValue, - res_state statp, int what) -{ - DWORD size = 0; - LONG res; - LPBYTE list; - int debug = statp->options & RES_DEBUG; - - res = RegQueryValueEx( hKey, KeyValue, NULL, NULL, NULL, &size); - DPRINTF(debug, "value %s, error %lu (Windows), size %lu\n", - KeyValue, res, size); - if ((res == ERROR_SUCCESS) && (size > 1)) { - if (!(list = (LPBYTE) alloca(size))) { - DPRINTF(debug, "alloca: %s\n", strerror(errno)); - } - else if ((res = RegQueryValueEx( hKey, KeyValue, NULL, NULL, list, - &size )) != ERROR_SUCCESS) { - DPRINTF(debug, "RegQueryValueEx: error %lu (Windows)\n", res); - } - else if (what == 0) { /* Get the addresses */ - BYTE *ap, *srch; - int numAddresses = 0; - for (ap = list; ap < list + size && *ap; ap = srch) { - /* The separation character can be 0, ' ', or ','. */ - for (srch = ap; *srch && (isdigit(*srch) || *srch == '.' ); srch++); - *srch++ = 0; - if (numAddresses < DIM(statp->nsaddr_list)) { - DPRINTF(debug, "server \"%s\"\n", ap); - statp->nsaddr_list[numAddresses].sin_addr.s_addr = cygwin_inet_addr((char *) ap); - if ( statp->nsaddr_list[numAddresses].sin_addr.s_addr != 0 ) - numAddresses++; - } - else - DPRINTF(debug, "no space for server \"%s\"\n", ap); - } - statp->nscount = numAddresses; - } - else /* Parse the search line */ - minires_get_search((char *) list, statp); - } - return; -} - -/*********************************************************************** - * - get_registry_dns: - - Read the registry to get dns server addresses in Network Byte Order, - and set statp->nscount (for NT <= 4.0) - Read the registry SearchList - -***********************************************************************/ - -static void get_registry_dns(res_state statp) -{ - HKEY hKey; - DWORD res; - const char *keyName = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"; - - DPRINTF(statp->options & RES_DEBUG, "key %s\n", keyName); - if ((res = RegOpenKeyEx( HKEY_LOCAL_MACHINE, keyName, 0, - KEY_QUERY_VALUE | KEY_READ, &hKey)) != ERROR_SUCCESS) { - DPRINTF(statp->options & RES_DEBUG, "RegOpenKeyEx: error %lu (Windows)\n", res); - return; - } - - if (statp->nscount == 0) - get_registry_dns_items(hKey, "NameServer", statp, 0); - if (statp->nscount == 0) - get_registry_dns_items(hKey, "DhcpNameServer", statp, 0); - if (statp->dnsrch[0] == NULL) - get_registry_dns_items(hKey, "SearchList", statp, 1); - - RegCloseKey(hKey); - - return; -} - -/*********************************************************************** - * - get_dns_info: Get the search list or the domain name - and the dns server addresses in Network Byte Order - Set statp->os_query if DnsQuery is available. - -***********************************************************************/ -void get_dns_info(res_state statp) -{ -#if MAX_HOSTNAME_LEN > MAXHOSTNAMELEN -#define MAX_HOSTNAME_SIZE (MAX_HOSTNAME_LEN + 1) -#else -#define MAX_HOSTNAME_SIZE (MAXHOSTNAMELEN + 1) -#endif -#if MAX_HOSTNAME_SIZE > 256 /* sizeof(defdname) */ -#error stap->defdname too short -#endif - - int res, debug = statp->options & RES_DEBUG; - - ULONG ulOutBufLen = 0; - DWORD dwRetVal; - IP_ADDR_STRING * pIPAddr; - FIXED_INFO * pFixedInfo; - int numAddresses = 0; - - if (statp->use_os - && ((dwRetVal = DnsQuery_A(NULL, 0, 0, NULL, NULL, NULL)) != ERROR_PROC_NOT_FOUND)) - { - DPRINTF(debug, "using dnsapi.dll %d\n", dwRetVal); - statp->os_query = (typeof(statp->os_query)) cygwin_query; - /* We just need the search list. Avoid loading iphlpapi. */ - statp->nscount = -1; - } - - if (statp->nscount != 0) - goto use_registry; - - /* First call to get the buffer length we need */ - dwRetVal = GetNetworkParams((FIXED_INFO *) 0, &ulOutBufLen); - if (dwRetVal != ERROR_BUFFER_OVERFLOW) { - DPRINTF(debug, "GetNetworkParams: error %lu (Windows)\n", dwRetVal); - goto use_registry; - } - if ((pFixedInfo = (FIXED_INFO *) alloca(ulOutBufLen)) == 0) { - DPRINTF(debug, "alloca: %s\n", strerror(errno)); - goto use_registry; - } - if ((dwRetVal = GetNetworkParams(pFixedInfo, & ulOutBufLen))) { - DPRINTF(debug, "GetNetworkParams: error %lu (Windows)\n", dwRetVal); - goto use_registry; - } - - DPRINTF(debug, "GetNetworkParams: OK\n"); - /* Record server addresses, up to array size */ - for (pIPAddr = &(pFixedInfo->DnsServerList), numAddresses = 0; - pIPAddr; - pIPAddr = pIPAddr->Next) { - if (numAddresses < DIM(statp->nsaddr_list)) { - DPRINTF(debug, "server \"%s\"\n", pIPAddr->IpAddress.String); - statp->nsaddr_list[numAddresses].sin_addr.s_addr = cygwin_inet_addr(pIPAddr->IpAddress.String); - if (statp->nsaddr_list[numAddresses].sin_addr.s_addr != 0) { - numAddresses++; - statp->nscount++; - } - } - else - DPRINTF(debug, "no space for server \"%s\"\n", pIPAddr->IpAddress.String); - } - - use_registry: - get_registry_dns(statp); - - if (!statp->dnsrch[0]) { - statp->defdname[sizeof(statp->defdname) - 1] = 0; - if (!(res = getdomainname(statp->defdname, sizeof(statp->defdname)))) { - if (statp->defdname[0] && !statp->defdname[sizeof(statp->defdname) - 1]) - statp->dnsrch[0] = statp->defdname; - } - DPRINTF(debug, "getdomainname \"%s\"\n", - (res)? strerror(errno) : statp->defdname); - } -} - -#else -/*********************************************************************** - * - Default interface code - -***********************************************************************/ - -void get_dns_info(res_state statp) -{ - return; -} - -#endif - - - -#if 0 -#define DNS_ERROR_RCODE_FORMAT_ERROR 9001L -#define DNS_ERROR_RCODE_SERVER_FAILURE 9002L -#define DNS_ERROR_RCODE_NAME_ERROR 9003L -#define DNS_ERROR_RCODE_NOT_IMPLEMENTED 9004L -#define DNS_ERROR_RCODE_REFUSED 9005L -#define DNS_ERROR_RCODE_YXDOMAIN 9006L -#define DNS_ERROR_RCODE_YXRRSET 9007L -#define DNS_ERROR_RCODE_NXRRSET 9008L -#define DNS_ERROR_RCODE_NOTAUTH 9009L -#define DNS_ERROR_RCODE_NOTZONE 9010L -#define DNS_ERROR_RCODE_BADSIG 9016L -#define DNS_ERROR_RCODE_BADKEY 9017L -#define DNS_ERROR_RCODE_BADTIME 9018L -#define DNS_INFO_NO_RECORDS 9501L -#define DNS_ERROR_BAD_PACKET 9502L -#define DNS_ERROR_NO_PACKET 9503L -#define DNS_ERROR_RCODE 9504L -#define DNS_ERROR_UNSECURE_PACKET 9505L -#define DNS_ERROR_INVALID_TYPE 9551L -#define DNS_ERROR_INVALID_IP_ADDRESS 9552L -#define DNS_ERROR_INVALID_PROPERTY 9553L -#define DNS_ERROR_TRY_AGAIN_LATER 9554L -#define DNS_ERROR_NOT_UNIQUE 9555L -#define DNS_ERROR_NON_RFC_NAME 9556L -#define DNS_STATUS_FQDN 9557L -#define DNS_STATUS_DOTTED_NAME 9558L -#define DNS_STATUS_SINGLE_PART_NAME 9559L -#define DNS_ERROR_INVALID_NAME_CHAR 9560L -#define DNS_ERROR_NUMERIC_NAME 9561L -#define DNS_ERROR_NOT_LALOWED_ON_ROOT_SERVER 9562L -#define DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION 9563L -#define DNS_ERROR_CANNOT_FIND_ROOT_HINTS 9564L -#define DNS_ERROR_INCONSISTENT_ROOT_HINTS 9565L -#define DNS_ERROR_ZONE_DOES_NOT_EXIST 9601L -#define DNS_ERROR_NO_ZONE_INFO 9602L -#define DNS_ERROR_INVALID_ZONE_OPERATION 9603L -#define DNS_ERROR_ZONE_CONFIGURATION_ERROR 9604L -#define DNS_ERROR_ZONE_HAS_NO_SOA_RECORD 9605L -#define DNS_ERROR_ZONE_HAS_NO_NS_RECORDS 9606L -#define DNS_ERROR_ZONE_LOCKED 9607L -#define DNS_ERROR_ZONE_CREATION_FAILED 9608L -#define DNS_ERROR_ZONE_ALREADY_EXISTS 9609L -#define DNS_ERROR_AUTOZONE_ALREADY_EXISTS 9610L -#define DNS_ERROR_INVALID_ZONE_TYPE 9611L -#define DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP 9612L -#define DNS_ERROR_ZONE_NOT_SECONDARY 9613L -#define DNS_ERROR_NEED_SECONDARY_ADDRESSES 9614L -#define DNS_ERROR_WINS_INIT_FAILED 9615L -#define DNS_ERROR_NEED_WINS_SERVERS 9616L -#define DNS_ERROR_NBSTAT_INIT_FAILED 9617L -#define DNS_ERROR_SOA_DELETE_INVALID 9618L -#define DNS_ERROR_FORWARDER_ALREADY_EXISTS 9619L -#define DNS_ERROR_ZONE_REQUIRES_MASTER_IP 9620L -#define DNS_ERROR_ZONE_IS_SHUTDOWN 9621L -#define DNS_ERROR_PRIMARY_REQUIRES_DATAFILE 9651L -#define DNS_ERROR_INVALID_DATAFILE_NAME 9652L -#define DNS_ERROR_DATAFILE_OPEN_FAILURE 9653L -#define DNS_ERROR_FILE_WRITEBACK_FAILED 9654L -#define DNS_ERROR_DATAFILE_PARSING 9655L -#define DNS_ERROR_RECORD_DOES_NOT_EXIST 9701L -#define DNS_ERROR_RECORD_FORMAT 9702L -#define DNS_ERROR_NODE_CREATION_FAILED 9703L -#define DNS_ERROR_UNKNOWN_RECORD_TYPE 9704L -#define DNS_ERROR_RECORD_TIMED_OUT 9705L -#define DNS_ERROR_NAME_NOT_IN_ZONE 9706L -#define DNS_ERROR_CNAME_LOOP 9707L -#define DNS_ERROR_NODE_IS_CNAME 9708L -#define DNS_ERROR_CNAME_COLLISION 9709L -#define DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT 9710L -#define DNS_ERROR_RECORD_ALREADY_EXISTS 9711L -#define DNS_ERROR_SECONDARY_DATA 9712L -#define DNS_ERROR_NO_CREATE_CACHE_DATA 9713L -#define DNS_ERROR_NAME_DOES_NOT_EXIST 9714L -#define DNS_WARNING_PTR_CREATE_FAILED 9715L -#define DNS_WARNING_DOMAIN_UNDELETED 9716L -#define DNS_ERROR_DS_UNAVAILABLE 9717L -#define DNS_ERROR_DS_ZONE_ALREADY_EXISTS 9718L -#define DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE 9719L -#define DNS_INFO_AXFR_COMPLETE 9751L -#define DNS_ERROR_AXFR 9752L -#define DNS_INFO_ADDED_LOCAL_WINS 9753L -#define DNS_STATUS_CONTINUE_NEEDED 9801L -#define DNS_ERROR_NO_TCPIP 9851L -#define DNS_ERROR_NO_DNS_SERVERS 9852L -#define DNS_ERROR_DP_DOES_NOT_EXIST 9901L -#define DNS_ERROR_DP_ALREADY_EXISTS 9902L -#define DNS_ERROR_DP_NOT_ENLISTED 9903L -#define DNS_ERROR_DP_ALREADY_ENLISTED 9904L -#define DNS_ERROR_DP_NOT_AVAILABLE 9905L -#endif diff --git a/winsup/cygwin/libc/minires.c b/winsup/cygwin/libc/minires.c deleted file mode 100644 index 7d0a6ab06..000000000 --- a/winsup/cygwin/libc/minires.c +++ /dev/null @@ -1,904 +0,0 @@ -/* minires.c. Stub synchronous resolver for Cygwin. - - Copyright 2006 Red Hat, Inc. - - Written by Pierre A. Humblet <Pierre.Humblet@ieee.org> - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#include "minires.h" - -/*********************************************************************** - -Utilities - -***********************************************************************/ -/*********************************************************************** - -dprintf -***********************************************************************/ -void minires_dprintf(const char * format, ...) -{ - va_list args; - - va_start(args, format); - fprintf(stderr, "Minires: "); - vfprintf(stderr, format, args); - va_end(args); -} - -/*********************************************************************** - -scanline -Put pointers in list[] to the beginning of each space or comma delimited -word in "in", and put the lengths in sizes[] (counting the final 0). -Return the number of words found -***********************************************************************/ -static int scanline(char * in, char **list, int * sizes, int maxnum) -{ - int i; - char * startp; - for (i = 0; i < maxnum; i++) { - while((*in) && (isspace(*in) || *in == ',')) in++; - if (*in == 0) - break; - startp = in++; - while((*in) && !isspace(*in) && *in != ',') in++; - list[i] = startp; - sizes[i] = in - startp + 1; - if (*in) - *in++ = 0; - } - return i; -} - -/*********************************************************************** - -Read the search string. - -***********************************************************************/ -void minires_get_search(char * string, res_state statp) -{ - char * words[MAXDNSRCH+1], * ptr; - int sizes[MAXDNSRCH+1]; - int i, j, debug = statp->options & RES_DEBUG; - - i = scanline(string, words, sizes, MAXDNSRCH+1); - ptr = statp->defdname; - for (j = 0; j < i; j++) { - if (j < MAXDNSRCH - && ptr + sizes[j] < &statp->defdname[DIM(statp->defdname)]) { - statp->dnsrch[j] = strcpy(ptr, words[j]); - statp->dnsrch[j+1] = NULL; - ptr += sizes[j]; - DPRINTF(debug, "search \"%s\"\n", words[j]); - } - else - DPRINTF(debug, "no space for \"%s\"\n", words[j]); - } -} - -/*********************************************************************** - -Read options - - -***********************************************************************/ -static void get_options(res_state statp, int i, char **words) -{ - char *ptr; - int value; - - while (i-- > 0) { - if (!strcasecmp("debug", words[i])) { - statp->options |= RES_DEBUG; - DPRINTF(statp->options & RES_DEBUG, "%s: 1\n", words[i]); - continue; - } - if (!strcasecmp("osquery", words[i])) { - statp->use_os = 1; - DPRINTF(statp->options & RES_DEBUG, "%s: 1\n", words[i]); - continue; - } - - if ((ptr = strchr(words[i], ':'))) { - *ptr++ = 0; - value = atoi(ptr); - /* Not supported - if (!strcasecmp("ndots", words[i])) { - statp->ndots = value; - continue; - } - */ - if (!strcasecmp("retry", words[i])) { - if (value < 1) - value = 1; - statp->retry = value; - DPRINTF(statp->options & RES_DEBUG, "%s: %d\n", words[i], value); - continue; - } - if (!strcasecmp("retrans", words[i])) { - if (value < 1) - value = 1; - statp->retrans = value; - DPRINTF(statp->options & RES_DEBUG, "%s: %d\n", words[i], value); - continue; - } - } - DPRINTF(statp->options & RES_DEBUG, "unknown option: \"%s\"\n", words[i]); - } -} - -/*********************************************************************** - -Read the resolv.conf file. -We only look for nameserver, domain, search and options - -***********************************************************************/ -#if MAXNS > MAXDNSRCH + 1 -#define MAXSIZE MAXNS -#else -#define MAXSIZE MAXDNSRCH + 1 /* Make unused one visible */ -#endif -static void get_resolv(res_state statp) -{ - FILE * fd; - char *words[MAXSIZE + 1], line[4096], *ptr; - int sizes[DIM(words)]; - int i, j, ns = 0, have_search, have_address, debug = statp->options & RES_DEBUG; - - fd = fopen(_PATH_RESCONF, "r"); - DPRINTF(debug, _PATH_RESCONF ": %s\n", fd?"OK":strerror(errno)); - if (fd == NULL) - return; - - statp->use_os = 0; /* Do not use os_query, except if allowed by "options" */ - have_search = (statp->dnsrch[0] != NULL); - have_address = (statp->nscount != 0); - - while ( fgets(line, sizeof(line), fd) != 0) { - DPRINTF(debug, "resolv.conf %s", line); - if ((i = scanline(line, words, sizes, DIM(words))) > 0) { - if (!have_address - && !strncasecmp("nameserver", words[0], sizes[0])) { - for ( j = 1; j < i ; j++) { - unsigned int address; - address = cygwin_inet_addr(words[j]); - if (address == -1) { - DPRINTF(debug, "invalid server \"%s\"\n", words[j]); - } - else if (ns >= MAXNS) { - DPRINTF(debug, "no space for server \"%s\"\n", words[j]); - } - else { - statp->nsaddr_list[ns++].sin_addr.s_addr = address; - statp->nscount++; - DPRINTF(debug, "server \"%s\"\n", words[j]); - } - } - } - else if (!have_search - && (!strncasecmp("search", words[0], sizes[0]) - || !strncasecmp("domain", words[0], sizes[0]))) { - ptr = statp->defdname; - for (j = 0; j + 1 < i; j++) { - if (j < MAXDNSRCH - && ptr + sizes[j + 1] < &statp->defdname[DIM(statp->defdname)]) { - statp->dnsrch[j] = strcpy(ptr, words[j+1]); - statp->dnsrch[j+1] = 0; - ptr += sizes[j+1]; - DPRINTF(debug, "domain|search \"%s\"\n", statp->dnsrch[j]); - } - else { - DPRINTF(debug, "no space for \"%s\"\n", words[j+1]); - } - } - } - /* Options line */ - else if (!strncasecmp("options", words[0], sizes[0])) - get_options(statp, i - 1, &words[1]); - } - } - fclose(fd); - return; -} - -/****************************************************************************/ -/* - open_sock() - Create a datagram socket and call bind. - -****************************************************************************/ - -static int open_sock(struct sockaddr_in *CliAddr, int debug) -{ - int fd; - - DPRINTF(debug, "opening UDP socket\n"); - - /* Create a datagram socket */ - if ((fd = cygwin_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - DPRINTF(debug, "socket(UDP): %s\n", strerror(errno)); - return -1; - } - CliAddr->sin_family = AF_INET; - CliAddr->sin_addr.s_addr = htonl(INADDR_ANY); - CliAddr->sin_port = htons(0); - bzero(CliAddr->sin_zero, sizeof(CliAddr->sin_zero)); - /* Get a port */ - if (cygwin_bind(fd, (struct sockaddr *) CliAddr, sizeof(*CliAddr)) < 0) { - DPRINTF(debug, "bind: %s\n", strerror(errno)); - return -1; - } - return fd; -} - -/***************************************************************** - * - __res_state() - Undocumented but public. Accessed through _res - - *****************************************************************/ -static struct __res_state res; -struct __res_state *__res_state(void) -{ - return & res; -} - -/***************************************************************** - * - res_init() - - *****************************************************************/ -int res_ninit(res_state statp) -{ - int i; - - statp->res_h_errno = NETDB_SUCCESS; - statp->nscount = 0; - statp->os_query = NULL; - statp->retrans = RES_TIMEOUT; /* timeout in seconds */ - statp->retry = RES_MAXRETRY; /* max number of retries */ - statp->use_os = 1; /* use os_query if available and allowed by get_resolv */ - statp->mypid = -1; - statp->sockfd = -1; - - for (i = 0; i < DIM(statp->dnsrch); i++) statp->dnsrch[i] = 0; - - /* resolv.conf (dns servers & search list)*/ - get_resolv(statp); - /* Get dns servers and search list from an os-specific routine, set os_query */ - get_dns_info(statp); - - if (statp->nscount == 0 && !statp->os_query) { - errno = ENONET; - statp->res_h_errno = NETDB_INTERNAL; - DPRINTF(statp->options & RES_DEBUG, "no dns server found\n"); - return -1; - } - for (i = 0; i < statp->nscount; i++) { - statp->nsaddr_list[i].sin_family = AF_INET; - statp->nsaddr_list[i].sin_port = htons(NAMESERVER_PORT); - bzero(statp->nsaddr_list[i].sin_zero, sizeof(statp->nsaddr_list[i].sin_zero)); - } - /* Only debug may be set before calling init */ - statp->options &= RES_DEBUG; - statp->options |= RES_INIT | RES_DEFAULT; - return 0; -} - -int res_init() -{ - int r = res_ninit(& res); - h_errno = res.res_h_errno; - return r; -} - -/***************************************************************** - * - res_close() - - *****************************************************************/ -void res_nclose(res_state statp) -{ - int res; - if (statp->sockfd != -1) { - res = close(statp->sockfd); - DPRINTF(statp->options & RES_DEBUG, "close sockfd %d: %s\n", - statp->sockfd, (res == 0)?"OK":strerror(errno)); - statp->sockfd = -1; - } -} - -void res_close() -{ - res_nclose(& res); -} - -/***************************************************************** - * - get_tcp_buf() - - *****************************************************************/ -static int get_tcp_buf(int fd, unsigned char *buf, int size, int debug) -{ - int res; - while (size > 0) { - if ((res = read(fd, buf, size)) < 0) { - DPRINTF(debug, "read: %s\n", strerror(errno)); - return -1; - } - DPRINTF(debug, "read %d out of %d\n", res, size); - size -= res; - buf += res; - } - return 0; -} - -/***************************************************************** - * - get_tcp() - - *****************************************************************/ -static int get_tcp(struct sockaddr_in *CliAddr, - const unsigned char * MsgPtr, int MsgLength, - unsigned char * AnsPtr, int AnsLength, int debug) -{ - int fd, res = -1; - unsigned short ans_length; - union {short len; u_char buf[sizeof(short)];} len_buf; - - DPRINTF(debug, "retrying with TCP\n"); - - /* Create a tcp socket */ - if ((fd = cygwin_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { - DPRINTF(debug, "socket(TCP): %s\n", strerror(errno)); - return -1; - } - - if (cygwin_connect(fd, (struct sockaddr *) CliAddr, sizeof(* CliAddr)) < 0) { - DPRINTF(debug, "connect: %s\n", strerror(errno)); - goto done; - } - - /* Send the length then the message */ - len_buf.len = htons(MsgLength); - if (write(fd, len_buf.buf, sizeof(len_buf)) != sizeof(len_buf) - || write(fd, MsgPtr, MsgLength) != MsgLength) { - DPRINTF(debug, "write: %s\n", strerror(errno)); - goto done; - } - - /* Read the answer length */ - if (get_tcp_buf(fd, len_buf.buf, sizeof(len_buf), debug)) - goto done; - ans_length = ntohs(len_buf.len); - - /* Read the answer */ - if (get_tcp_buf(fd, AnsPtr, MIN(ans_length, AnsLength), debug)) - goto done; - res = ans_length; - - done: - close (fd); - return res; -} - -/***************************************************************** - ** - res_send - Assumes that the message is a query starting with a short id. - Handles retransmissions until that id is received. - -*****************************************************************/ -int res_nsend( res_state statp, const unsigned char * MsgPtr, - int MsgLength, unsigned char * AnsPtr, int AnsLength) -{ - /* Current server, shared by all tasks */ - volatile static unsigned int SServ = 0XFFFFFFFF; - int tcp; - const int debug = statp->options & RES_DEBUG; - - fd_set fdset_read; - int rslt, addrLen, transNum, wServ; - struct sockaddr_in mySockAddr, dnsSockAddr; - struct timeval timeOut; - - statp->res_h_errno = NETDB_SUCCESS; - if (((statp->options & RES_INIT) == 0) && (res_ninit(statp) != 0)) - return -1; - - /* Close the socket if it had been opened before a fork. - Reuse of pid's cannot hurt */ - if ((statp->sockfd != -1) && (statp->mypid != getpid())) { - res_nclose(statp); - } - - /* Open a socket for this process */ - if (statp->sockfd == -1) { - /* Create a socket and bind it (to any port) */ - statp->sockfd = open_sock(& mySockAddr, debug); - if (statp->sockfd < 0 ) { - statp->res_h_errno = NETDB_INTERNAL; - return -1; - } - /* Set close on exec flag */ - if (fcntl64(statp->sockfd, F_SETFD, 1) == -1) { - DPRINTF(debug, "fcntl: %s\n", - strerror(errno)); - statp->res_h_errno = NETDB_INTERNAL; - return -1; - } - statp->mypid = getpid(); - if (SServ == 0XFFFFFFFF) /* Pseudo random */ - SServ = statp->mypid % statp->nscount; - } - - transNum = 0; - while ( transNum++ < statp->retry) { - if ((wServ = SServ + 1) >= statp->nscount) - wServ = 0; - SServ = wServ; - /* Send the message */ - rslt = cygwin_sendto(statp->sockfd, MsgPtr, MsgLength, 0, - (struct sockaddr *) &statp->nsaddr_list[wServ], - sizeof(struct sockaddr_in)); - DPRINTF(debug, "sendto: server %08x sockfd %d %s\n", - statp->nsaddr_list[wServ].sin_addr.s_addr, - statp->sockfd, (rslt == MsgLength)?"OK":strerror(errno)); - if (rslt != MsgLength) { - statp->res_h_errno = NETDB_INTERNAL; - return -1; - }; - /* - Wait for a reply with select() - */ - FD_ZERO(&fdset_read); - FD_SET (statp->sockfd, &fdset_read ); - timeOut.tv_sec = statp->retrans; - timeOut.tv_usec = 0; - rslt = cygwin_select(statp->sockfd + 1, &fdset_read, NULL, NULL, &timeOut); - if ( rslt == 0 ) { /* Timeout */ - DPRINTF(statp->options & RES_DEBUG, "timeout for server %08x\n", - statp->nsaddr_list[wServ].sin_addr.s_addr); - continue; - } - else if ((rslt != 1) || (FD_ISSET(statp->sockfd, &fdset_read) == 0)) { - DPRINTF(debug, "select: %s\n", strerror(errno)); - statp->res_h_errno = NETDB_INTERNAL; - return -1; - } - - addrLen = sizeof(dnsSockAddr); - rslt = cygwin_recvfrom(statp->sockfd, AnsPtr, AnsLength, 0, - (struct sockaddr *) & dnsSockAddr, & addrLen); - if (rslt <= 0) { - DPRINTF(debug, "recvfrom: %s\n", strerror(errno)); - statp->res_h_errno = NETDB_INTERNAL; - return -1; - } - /* - Prepare to retry with tcp - */ - for (tcp = 0; tcp < 2; tcp++) { - /* Check if this is the message we expected */ - if ((*MsgPtr == *AnsPtr) /* Ids match */ - && (*(MsgPtr + 1) == *(AnsPtr + 1)) -/* We have stopped checking this because the question may not be present on error, - in particular when the name in the question is not a valid name. - Simply check that the header is present. */ - && (rslt >= HFIXEDSZ) -/* && (rslt >= MsgLength ) - && (memcmp(MsgPtr + HFIXEDSZ, AnsPtr + HFIXEDSZ, MsgLength - HFIXEDSZ) == 0) */ - && ((AnsPtr[2] & QR) != 0)) { - - DPRINTF(debug, "answer %u from %08x. Error %d. Count %d.\n", - rslt, dnsSockAddr.sin_addr.s_addr, - AnsPtr[3] & ERR_MASK, AnsPtr[6]*256 + AnsPtr[7]); -#if 0 - NETDB_INTERNAL -1 /* see errno */ - NETDB_SUCCESS 0 /* no problem */ - HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ - TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */ - Also seen returned by some servers when the name is too long - NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ - NO_DATA 4 /* Valid name, no data record of requested type */ -#endif - if ((AnsPtr[3] & ERR_MASK) == NOERROR) { - if ((AnsPtr[2] & TC) && !(statp->options & RES_IGNTC)) { /* Truncated. Try TCP */ - rslt = get_tcp(&statp->nsaddr_list[wServ], MsgPtr, MsgLength, - AnsPtr, AnsLength, statp->options & RES_DEBUG); - continue; - } - else if ((AnsPtr[6] | AnsPtr[7])!= 0) - return rslt; - else - statp->res_h_errno = NO_DATA; - } - else { - /* return HOST_NOT_FOUND even for non-authoritative answers */ - if ((AnsPtr[3] & ERR_MASK) == NXDOMAIN) - statp->res_h_errno = HOST_NOT_FOUND; - else if ((AnsPtr[3] & ERR_MASK) == SERVFAIL) - statp->res_h_errno = TRY_AGAIN; - else - statp->res_h_errno = NO_RECOVERY; - } - return -1; - } - else { - DPRINTF(debug, "unexpected answer %u from %x to query to %x\n", - rslt, dnsSockAddr.sin_addr.s_addr, - statp->nsaddr_list[wServ].sin_addr.s_addr); - break; - } - } /* TCP */ - } - DPRINTF(debug, "too many retries\n"); - statp->res_h_errno = TRY_AGAIN; - return -1; -} - -int res_send( const unsigned char * MsgPtr, int MsgLength, - unsigned char * AnsPtr, int AnsLength) -{ - int r = res_nsend(& res, MsgPtr, MsgLength, AnsPtr, AnsLength); - h_errno = res.res_h_errno; - return r; -} - -/***************************************************************** - * - res_mkquery - - Return: packet size - -1 name format is incorrect -*****************************************************************/ -int res_nmkquery (res_state statp, - int op, const char * dnameptr, int qclass, int qtype, - const unsigned char * dataptr, int datalen, - const unsigned char * newrr, unsigned char * buf, int buflen) -{ - int i, len; - short id; - - if (op == QUERY) { - /* Write the name and verify buffer length */ - len = dn_comp(dnameptr, buf + HFIXEDSZ, buflen - HFIXEDSZ - QFIXEDSZ, NULL, NULL); - if (len < 0) { - DPRINTF(statp->options & RES_DEBUG, - "\"%s\" invalid or buffer too short\n", dnameptr); - statp->res_h_errno = NETDB_INTERNAL; - return -1; - } - /* Fill the header */ - id = statp->id; - PUTSHORT(id, buf); - PUTSHORT(RD, buf); - PUTSHORT(1, buf); /* Number of questions */ - for (i = 0; i < 3; i++) - PUTSHORT(0, buf); /* Number of answers */ - - /* Write qtype and qclass */ - buf += len; - PUTSHORT(qtype, buf); - PUTSHORT(qclass, buf); - return len + 16; /* packet size */ - } - else { /* Not implemented */ - errno = ENOSYS; - statp->res_h_errno = NETDB_INTERNAL; - return -1; - } -} - -int res_mkquery (int op, const char * dnameptr, int qclass, int qtype, - const unsigned char * dataptr, int datalen, - const unsigned char * newrr, unsigned char * buf, int buflen) -{ - int r = res_nmkquery (& res, op, dnameptr, qclass, qtype, - dataptr, datalen, newrr, buf, buflen); - h_errno = res.res_h_errno; - return r; - -} - -/***************************************************************** - * res_query() - *****************************************************************/ - -int res_nquery( res_state statp, const char * DomName, int Class, int Type, - unsigned char * AnsPtr, int AnsLength) -{ - u_char packet[PACKETSZ]; - int len; - - DPRINTF(statp->options & RES_DEBUG, "query \"%s\" type %d\n", DomName, Type); - statp->res_h_errno = NETDB_SUCCESS; - - /* If a hook exists to a native implementation, use it */ - if (statp->os_query) - return ((os_query_t *) statp->os_query)(statp, DomName, Class, Type, AnsPtr, AnsLength); - - if ((len = res_nmkquery (statp, QUERY, DomName, Class, Type, - 0, 0, 0, packet, PACKETSZ)) < 0) - return -1; - return res_nsend( statp, packet, len, AnsPtr, AnsLength); -} - -int res_query( const char * DomName, int Class, int Type, unsigned char * AnsPtr, int AnsLength) -{ - int r = res_nquery(& res, DomName, Class, Type, AnsPtr, AnsLength); - h_errno = res.res_h_errno; - return r; -} - -/***************************************************************** - * res_querydomain() - *****************************************************************/ -int res_nquerydomain( res_state statp, const char * Name, const char * DomName, - int Class, int Type, unsigned char * AnsPtr, int AnsLength) -{ - char fqdn[MAXDNAME], *ptr; - int nlen; - - if (!DomName) - ptr = (char *) Name; - else if ((nlen = strlen(Name)) >= sizeof(fqdn) - 1) - goto error; - else { - strcpy(fqdn, Name); - ptr = &fqdn[nlen]; - if (nlen && *(ptr - 1) != '.') - *(ptr++ - 1) = '.'; - fqdn[sizeof(fqdn) - 1] = 0; - strncpy(ptr, DomName, sizeof(fqdn) - (ptr - fqdn)); - if (fqdn[sizeof(fqdn) - 1]) - goto error; - ptr = fqdn; - } - return res_nquery(statp, ptr, Class, Type, AnsPtr, AnsLength); - - error: - DPRINTF(statp->options & RES_DEBUG, "querydomain: name too long\n"); - errno = EINVAL; - statp->res_h_errno = NETDB_INTERNAL;; - return -1; -} - -int res_querydomain( const char * Name, const char * DomName, int Class, - int Type, unsigned char * AnsPtr, int AnsLength) -{ - int r = res_nquerydomain(& res, Name, DomName, Class, Type, AnsPtr, - AnsLength); - h_errno = res.res_h_errno; - return r; -} - -/***************************************************************** - * - res_search() - - *****************************************************************/ - -int res_nsearch( res_state statp, const char * DomName, int Class, int Type, - unsigned char * AnsPtr, int AnsLength) -{ - int len, stat, i; - char fullDomName[MAXDNAME], *ptr, *sptr; - - DPRINTF(statp->options & RES_DEBUG, "search \"%s\" type %d\n", DomName, Type); - - if (((statp->options & RES_INIT) == 0) && (res_ninit(statp) != 0)) - return -1; - - stat = res_nquery( statp, DomName, Class, Type, AnsPtr, AnsLength); - - /* Check if will skip search */ - if (statp->res_h_errno != HOST_NOT_FOUND /* Success or hard failure */ - || ((ptr = strrchr(DomName, '.')) && (!*(ptr+1))) /* Final dot */ - || (((statp->options & RES_DNSRCH) == 0) /* Or no search */ - && ((ptr != NULL) /* And some dot */ - || ((statp->options & RES_DEFNAMES) == 0)))/* or no def domain */ - || (!(sptr = statp->dnsrch[0]))) - return stat; - - len = strlen(DomName); - if (len >= MAXDNAME - 1) /* Space for next dot */ - goto error; - strcpy(fullDomName, DomName); - fullDomName[len++] = '.'; - fullDomName[MAXDNAME - 1] = 0; /* Overflow indicator */ - i = 0; - do { - strncpy(fullDomName + len, sptr, MAXDNAME - len); - if (fullDomName[MAXDNAME - 1]) - goto error; - stat = res_nquery(statp, fullDomName, Class, Type, AnsPtr, AnsLength); - } while ((sptr = statp->dnsrch[++i]) != NULL - && statp->res_h_errno == HOST_NOT_FOUND - && (statp->options & RES_DNSRCH) != 0); - - /* Return last stat */ - return stat; - - error: - DPRINTF(statp->options & RES_DEBUG, "name too long during search\n"); - errno = EINVAL; - statp->res_h_errno = NETDB_INTERNAL; - return -1; -} - -int res_search( const char * DomName, int Class, int Type, - unsigned char * AnsPtr, int AnsLength) -{ - int r = res_nsearch(& res, DomName, Class, Type, AnsPtr, AnsLength); - h_errno = res.res_h_errno; - return r; -} - -/***************************************************************** - * dn_expand - *****************************************************************/ - -int dn_expand(const unsigned char *msg, const unsigned char *eomorig, - const unsigned char *comp_dn, char *exp_dn, int length) -{ - unsigned int len, complen = 0; - const unsigned char *comp_dn_orig = comp_dn; -/* char * exp_start = exp_dn; */ - - errno = EINVAL; - if (comp_dn >= eomorig) - goto expand_fail; - if ((len = *comp_dn++) == 0) /* Weird case */ - exp_dn++; - else do { - if (len <= MAXLABEL) { - if ((length -= (len + 1)) > 0 /* Need space for final . */ - && comp_dn + len <= eomorig) { - do { *exp_dn++ = *comp_dn++; } while (--len != 0); - *exp_dn++ = '.'; - } - else - goto expand_fail; - } - else if (len >= (128+64)) { - if (!complen) /* Still in the original field? */ - complen = (comp_dn - comp_dn_orig) + 1; - comp_dn = msg + (((len & ~(128+64)) << 8) + *comp_dn); - if (comp_dn >= eomorig) - goto expand_fail; - } - else - goto expand_fail; - } while ((len = *comp_dn++) != 0); - /* Replace last . with a 0 */ - *(--exp_dn) = 0; - if (!complen) - complen = comp_dn - comp_dn_orig; -/* fprintf(stderr, "dn_expand %s\n", exp_start); */ - return complen; - -expand_fail: -/* fprintf(stderr, "dn_expand fails\n"); */ - return -1; -} - - -/***************************************************************** - * - dn_comp - - Return -1 in case of overflow, but still fill buffer correctly. - We do not check the alphabet of the host names - nor the length of the compressed name and we - preserve the letter cases. - - *****************************************************************/ -int dn_comp(const char * exp_dn, u_char * comp_dn, int length, - u_char ** dnptrs, u_char ** lastdnptr) -{ - u_char *cptr = comp_dn, *dptr, *lptr, *rptr; - unsigned int i, len; - u_char * const eptr = comp_dn + length - 1; /* Last valid */ - - errno = EINVAL; - - if (*exp_dn == '.' && !*(exp_dn + 1)) - exp_dn++; - while (1) { - if (*exp_dn == '.' || cptr > eptr) - return -1; - if (*exp_dn == 0) { - *cptr++ = 0; - break; - } - /* Try to compress */ - if (dnptrs) { - for (i = 1; dnptrs[i]; i++) { - dptr = dnptrs[i]; - if (dptr >= comp_dn) /* Handle name.name */ - continue; - rptr = (u_char *) exp_dn; - len = *dptr++; - while (1) { - do { - if (*dptr++ != *rptr++) - goto next_dn; - } while (--len); - len = *dptr++; - if (len == 0) { /* last label */ - if (!*rptr || (*rptr == '.' && !*(rptr + 1))) { /* Full match */ - len = (dnptrs[i] - dnptrs[0]) | 0xC000; - /* Write pointer */ - *cptr++ = len >> 8; - if (cptr > eptr) - return -1; - *cptr++ = len; - goto done; - } - goto next_dn; - } - if (*rptr++ != '.') - goto next_dn; - if (len >= 128 + 64) { - dptr = dnptrs[0] + ((len - 128 - 64) << 8) + *dptr; - len = *dptr++; - } - } - next_dn: ; - } - /* Record label if asked and if space is available and if not too far off */ - if (lastdnptr && (lastdnptr != &dnptrs[i]) && (cptr - dnptrs[0]) < 0xC000) { - dnptrs[i] = cptr; - dnptrs[i+1] = NULL; - } - } - /* Write label */ - lptr = cptr++; /* Length byte */ - rptr = (u_char *) exp_dn; - do { - if (cptr <= eptr) - *cptr++ = *rptr; - } while ((*++rptr != '.') && (*rptr != 0)); - len = rptr - (u_char *) exp_dn; - if (len > MAXLABEL) - return -1; - *lptr = len; - exp_dn = (char *) rptr; - if (*exp_dn != 0) - exp_dn++; /* Skip over . */ - } - done: - return cptr - comp_dn; -} - -/***************************************************************** - * - dn_skipname - - Measures the compressed domain name length and returns it. - *****************************************************************/ -int dn_skipname(const unsigned char *comp_dn, const unsigned char *eom) -{ - int len; - const unsigned char *comp_dn_orig = comp_dn; - - do { - len = *comp_dn++; - if (len >= (128 + 64)) { - comp_dn++; - break; - } - if (len > MAXLABEL || - (comp_dn += len) > eom) - return -1; - } while (len != 0); - - return comp_dn - comp_dn_orig; -} diff --git a/winsup/cygwin/libc/minires.h b/winsup/cygwin/libc/minires.h deleted file mode 100644 index cda0b4c51..000000000 --- a/winsup/cygwin/libc/minires.h +++ /dev/null @@ -1,68 +0,0 @@ -/* minires.h. Stub synchronous resolver for Cygwin. - - Copyright 2006 Red Hat, Inc. - - Written by Pierre A. Humblet <Pierre.Humblet@ieee.org> - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#define __INSIDE_CYGWIN_NET__ - -#include "winsup.h" -#include <string.h> -#include <malloc.h> -#include <stdlib.h> -#include <netdb.h> -#include <ctype.h> -#include <sys/time.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdarg.h> -#include <sys/unistd.h> -#include <netdb.h> -#include <arpa/nameser.h> -#include <resolv.h> - -extern in_addr_t cygwin_inet_addr (const char *); -extern int cygwin_socket (int, int, int); -extern int cygwin_bind (int, const struct sockaddr *, socklen_t); -extern int cygwin_connect (int, const struct sockaddr *, socklen_t); -extern int cygwin_select (int, fd_set *, fd_set *, fd_set *, struct timeval *); -extern int cygwin_sendto (int, const void *, size_t, int, - const struct sockaddr *, socklen_t); -extern int cygwin_recvfrom (int, void *, size_t, int, struct sockaddr *, - socklen_t *); - -/* Number of elements is an array */ -#define DIM(x) (sizeof(x) / sizeof(*(x))) - -/* Definitions to parse the messages */ -#define RD (1<<8) /* Offset in a short */ -#define RA (1<<7) -#define QR (1<<7) /* Offsets in a char */ -#define TC (1<<1) -#define ERR_MASK 0xF - -/* Type for os specific res_lookup */ -typedef int (os_query_t) (res_state, const char *, int, int, u_char *, int); - -/* Special use of state elements */ -#define sockfd _vcsock -#define mypid _flags -#define os_query qhook -#define use_os pfcode - -#define DPRINTF(cond, format...) if (cond) minires_dprintf(format) - -/* Utility functions */ -void minires_dprintf(const char * format, ...); -void minires_get_search(char * string, res_state statp); -void get_dns_info(res_state statp); diff --git a/winsup/cygwin/libc/nftw.c b/winsup/cygwin/libc/nftw.c deleted file mode 100644 index bb1c92381..000000000 --- a/winsup/cygwin/libc/nftw.c +++ /dev/null @@ -1,126 +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; - -#if 0 - /* GLibc allows nfds < 1 and treats it as nfds == 1. Since nfds is - not used in this OpenBSD version anyway, just ignore it for - Linux compatibility. */ - /* XXX - nfds is currently unused */ - if (nfds < 1 || nfds > OPEN_MAX) { - errno = EINVAL; - return (-1); - } -#endif - - 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 843a21af7..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); - } - fcntl64(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 ca253f83e..000000000 --- a/winsup/cygwin/libc/rexec.cc +++ /dev/null @@ -1,416 +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 e2f710ae9..000000000 --- a/winsup/cygwin/libc/strptime.cc +++ /dev/null @@ -1,428 +0,0 @@ -/* $NetBSD: strptime.c,v 1.28 2008/04/28 20:23:01 martin Exp $ */ - -/*- - * Copyright (c) 1997, 1998, 2005, 2008 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code was contributed to The NetBSD Foundation by Klaus Klein. - * Heavily optimised by David Laight - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -#if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: strptime.c,v 1.28 2008/04/28 20:23:01 martin Exp $"); -#endif - -#ifdef __CYGWIN__ -#include "winsup.h" -#else -#include "namespace.h" -#include <sys/localedef.h> -#endif -#include <ctype.h> -#include <locale.h> -#include <string.h> -#include <time.h> -#include <tzfile.h> - -#ifdef __weak_alias -__weak_alias(strptime,_strptime) -#endif - -#ifdef __CYGWIN__ -typedef struct { - const char *abday[7]; - const char *day[7]; - const char *abmon[12]; - const char *mon[12]; - const char *am_pm[2]; - const char *d_t_fmt; - const char *d_fmt; - const char *t_fmt; - const char *t_fmt_ampm; -} _TimeLocale; - -_TimeLocale _DefaultTimeLocale = -{ - { - "Sun","Mon","Tue","Wed","Thu","Fri","Sat", - }, - { - "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", - "Friday", "Saturday" - }, - { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }, - { - "January", "February", "March", "April", "May", "June", "July", - "August", "September", "October", "November", "December" - }, - { - "AM", "PM" - }, - "%a %b %e %H:%M:%S %Y", - "%m/%d/%y", - "%H:%M:%S", - "%I:%M:%S %p" -}; - -_TimeLocale *_CurrentTimeLocale = &_DefaultTimeLocale; -#endif - -#define _ctloc(x) (_CurrentTimeLocale->x) - -/* - * We do not implement alternate representations. However, we always - * check whether a given modifier is allowed for a certain conversion. - */ -#define ALT_E 0x01 -#define ALT_O 0x02 -#define LEGAL_ALT(x) { if (alt_format & ~(x)) return NULL; } - -static const char gmt[4] = { "GMT" }; - -static const u_char *conv_num(const unsigned char *, int *, uint, uint); -static const u_char *find_string(const u_char *, int *, const char * const *, - const char * const *, int); - - -char * -strptime(const char *buf, const char *fmt, struct tm *tm) -{ - unsigned char c; - const unsigned char *bp; - int alt_format, i, split_year = 0; - const char *new_fmt; - - bp = (const u_char *)buf; - - while (bp != NULL && (c = *fmt++) != '\0') { - /* Clear `alternate' modifier prior to new conversion. */ - alt_format = 0; - i = 0; - - /* Eat up white-space. */ - if (isspace(c)) { - while (isspace(*bp)) - bp++; - continue; - } - - if (c != '%') - goto literal; - - -again: switch (c = *fmt++) { - case '%': /* "%%" is converted to "%". */ -literal: - if (c != *bp++) - return NULL; - LEGAL_ALT(0); - continue; - - /* - * "Alternative" modifiers. Just set the appropriate flag - * and start over again. - */ - case 'E': /* "%E?" alternative conversion modifier. */ - LEGAL_ALT(0); - alt_format |= ALT_E; - goto again; - - case 'O': /* "%O?" alternative conversion modifier. */ - LEGAL_ALT(0); - alt_format |= ALT_O; - goto again; - - /* - * "Complex" conversion rules, implemented through recursion. - */ - case 'c': /* Date and time, using the locale's format. */ - new_fmt = _ctloc(d_t_fmt); - goto recurse; - - case 'D': /* The date as "%m/%d/%y". */ - new_fmt = "%m/%d/%y"; - LEGAL_ALT(0); - goto recurse; - - case 'F': /* The date as "%Y-%m-%d". */ - new_fmt = "%Y-%m-%d"; - LEGAL_ALT(0); - goto recurse; - - case 'R': /* The time as "%H:%M". */ - new_fmt = "%H:%M"; - LEGAL_ALT(0); - goto recurse; - - case 'r': /* The time in 12-hour clock representation. */ - new_fmt =_ctloc(t_fmt_ampm); - LEGAL_ALT(0); - goto recurse; - - case 'T': /* The time as "%H:%M:%S". */ - new_fmt = "%H:%M:%S"; - LEGAL_ALT(0); - goto recurse; - - case 'X': /* The time, using the locale's format. */ - new_fmt =_ctloc(t_fmt); - goto recurse; - - case 'x': /* The date, using the locale's format. */ - new_fmt =_ctloc(d_fmt); - recurse: - bp = (const u_char *)strptime((const char *)bp, - new_fmt, tm); - LEGAL_ALT(ALT_E); - continue; - - /* - * "Elementary" conversion rules. - */ - case 'A': /* The day of week, using the locale's form. */ - case 'a': - bp = find_string(bp, &tm->tm_wday, _ctloc(day), - _ctloc(abday), 7); - LEGAL_ALT(0); - continue; - - case 'B': /* The month, using the locale's form. */ - case 'b': - case 'h': - bp = find_string(bp, &tm->tm_mon, _ctloc(mon), - _ctloc(abmon), 12); - LEGAL_ALT(0); - continue; - - case 'C': /* The century number. */ - i = 20; - bp = conv_num(bp, &i, 0, 99); - - i = i * 100 - TM_YEAR_BASE; - if (split_year) - i += tm->tm_year % 100; - split_year = 1; - tm->tm_year = i; - LEGAL_ALT(ALT_E); - continue; - - case 'd': /* The day of month. */ - case 'e': - bp = conv_num(bp, &tm->tm_mday, 1, 31); - LEGAL_ALT(ALT_O); - continue; - - case 'k': /* The hour (24-hour clock representation). */ - LEGAL_ALT(0); - /* FALLTHROUGH */ - case 'H': - bp = conv_num(bp, &tm->tm_hour, 0, 23); - LEGAL_ALT(ALT_O); - continue; - - case 'l': /* The hour (12-hour clock representation). */ - LEGAL_ALT(0); - /* FALLTHROUGH */ - case 'I': - bp = conv_num(bp, &tm->tm_hour, 1, 12); - if (tm->tm_hour == 12) - tm->tm_hour = 0; - LEGAL_ALT(ALT_O); - continue; - - case 'j': /* The day of year. */ - i = 1; - bp = conv_num(bp, &i, 1, 366); - tm->tm_yday = i - 1; - LEGAL_ALT(0); - continue; - - case 'M': /* The minute. */ - bp = conv_num(bp, &tm->tm_min, 0, 59); - LEGAL_ALT(ALT_O); - continue; - - case 'm': /* The month. */ - i = 1; - bp = conv_num(bp, &i, 1, 12); - tm->tm_mon = i - 1; - LEGAL_ALT(ALT_O); - continue; - - case 'p': /* The locale's equivalent of AM/PM. */ - bp = find_string(bp, &i, _ctloc(am_pm), NULL, 2); - if (tm->tm_hour > 11) - return NULL; - tm->tm_hour += i * 12; - LEGAL_ALT(0); - continue; - - case 'S': /* The seconds. */ - bp = conv_num(bp, &tm->tm_sec, 0, 61); - LEGAL_ALT(ALT_O); - continue; - - case 'U': /* The week of year, beginning on sunday. */ - case 'W': /* The week of year, beginning on monday. */ - /* - * 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. - */ - bp = conv_num(bp, &i, 0, 53); - LEGAL_ALT(ALT_O); - continue; - - case 'w': /* The day of week, beginning on sunday. */ - bp = conv_num(bp, &tm->tm_wday, 0, 6); - LEGAL_ALT(ALT_O); - continue; - - case 'Y': /* The year. */ - i = TM_YEAR_BASE; /* just for data sanity... */ - bp = conv_num(bp, &i, 0, 9999); - tm->tm_year = i - TM_YEAR_BASE; - LEGAL_ALT(ALT_E); - continue; - - case 'y': /* The year within 100 years of the epoch. */ - /* LEGAL_ALT(ALT_E | ALT_O); */ - bp = conv_num(bp, &i, 0, 99); - - if (split_year) - /* preserve century */ - i += (tm->tm_year / 100) * 100; - else { - split_year = 1; - if (i <= 68) - i = i + 2000 - TM_YEAR_BASE; - else - i = i + 1900 - TM_YEAR_BASE; - } - tm->tm_year = i; - continue; - - case 'Z': - tzset(); - if (strncmp((const char *)bp, gmt, 3) == 0) { - tm->tm_isdst = 0; -#ifdef TM_GMTOFF - tm->TM_GMTOFF = 0; -#endif -#ifdef TM_ZONE - tm->TM_ZONE = gmt; -#endif - bp += 3; - } else { - const unsigned char *ep; - - ep = find_string(bp, &i, - (const char * const *)tzname, - NULL, 2); - if (ep != NULL) { - tm->tm_isdst = i; -#ifdef TM_GMTOFF - tm->TM_GMTOFF = -(timezone); -#endif -#ifdef TM_ZONE - tm->TM_ZONE = tzname[i]; -#endif - } - bp = ep; - } - continue; - - /* - * Miscellaneous conversions. - */ - case 'n': /* Any kind of white-space. */ - case 't': - while (isspace(*bp)) - bp++; - LEGAL_ALT(0); - continue; - - - default: /* Unknown/unsupported conversion. */ - return NULL; - } - } - - return (char *) bp; -} - - -static const u_char * -conv_num(const unsigned char *buf, int *dest, uint llim, uint ulim) -{ - uint result = 0; - unsigned char ch; - - /* The limit also determines the number of valid digits. */ - uint rulim = ulim; - - ch = *buf; - if (ch < '0' || ch > '9') - return NULL; - - do { - result *= 10; - result += ch - '0'; - rulim /= 10; - ch = *++buf; - } while ((result * 10 <= ulim) && rulim && ch >= '0' && ch <= '9'); - - if (result < llim || result > ulim) - return NULL; - - *dest = result; - return buf; -} - -static const u_char * -find_string(const u_char *bp, int *tgt, const char * const *n1, - const char * const *n2, int c) -{ - int i; - unsigned int len; - - /* check full name - then abbreviated ones */ - for (; n1 != NULL; n1 = n2, n2 = NULL) { - for (i = 0; i < c; i++, n1++) { - len = strlen(*n1); - if (strncasecmp(*n1, (const char *)bp, len) == 0) { - *tgt = i; - return bp + len; - } - } - } - - /* Nothing matched */ - return NULL; -} diff --git a/winsup/cygwin/libc/xsique.cc b/winsup/cygwin/libc/xsique.cc deleted file mode 100644 index 9e2f76e74..000000000 --- a/winsup/cygwin/libc/xsique.cc +++ /dev/null @@ -1,48 +0,0 @@ -/* xsique.cc. XSI insque and remque functions. - - Copyright 2007 Red Hat, Inc. - -This file is part of Cygwin. - -This software is a copyrighted work licensed under the terms of the -Cygwin license. Please consult the file "CYGWIN_LICENSE" for -details. */ - -#include <search.h> - -extern "C" void -insque (void *velement, void *vpred) -{ - if (!velement) - return; - - struct qelem *element = (struct qelem *) velement; - struct qelem *pred = (struct qelem *) vpred; - struct qelem *succ; - - if (pred) - { - if ((succ = element->q_forw = pred->q_forw)) - succ->q_back = element; - pred->q_forw = element; - } - else - element->q_forw = NULL; - element->q_back = pred; -} - -extern "C" void -remque (void *velement) -{ - if (!velement) - return; - - struct qelem *pred = ((struct qelem *) velement)->q_back; - struct qelem *succ = ((struct qelem *) velement)->q_forw; - - if (succ) - succ->q_back = pred; - if (pred) - pred->q_forw = succ; -} - |