diff options
author | 2000-11-15 16:49:06 +0000 | |
---|---|---|
committer | 2000-11-15 16:49:06 +0000 | |
commit | 0d8c7ca818e93f30e0fe2974f2d274f5f16df8b5 (patch) | |
tree | 687021db7c1f68da06efc95dda3965c683bd5307 /dev-util | |
parent | binutils downgrade (diff) | |
download | gentoo-2-0d8c7ca818e93f30e0fe2974f2d274f5f16df8b5.tar.gz gentoo-2-0d8c7ca818e93f30e0fe2974f2d274f5f16df8b5.tar.bz2 gentoo-2-0d8c7ca818e93f30e0fe2974f2d274f5f16df8b5.zip |
*** empty log message ***
Diffstat (limited to 'dev-util')
-rw-r--r-- | dev-util/guile/files/net_db.c | 580 | ||||
-rw-r--r-- | dev-util/strace/files/stream.c | 810 |
2 files changed, 1390 insertions, 0 deletions
diff --git a/dev-util/guile/files/net_db.c b/dev-util/guile/files/net_db.c new file mode 100644 index 000000000000..58e8dd5aeb8f --- /dev/null +++ b/dev-util/guile/files/net_db.c @@ -0,0 +1,580 @@ +/* "net_db.c" network database support + * Copyright (C) 1995, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + * + * As a special exception, the Free Software Foundation gives permission + * for additional uses of the text contained in its release of GUILE. + * + * The exception is that, if you link the GUILE library with other files + * to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the GUILE library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the + * Free Software Foundation under the name GUILE. If you copy + * code from other Free Software Foundation releases into a copy of + * GUILE, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for GUILE, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. */ + +/* Software engineering face-lift by Greg J. Badros, 11-Dec-1999, + gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */ + + +/* Written in 1994 by Aubrey Jaffer. + * Thanks to Hallvard.Tretteberg@si.sintef.no for inspiration and discussion. + * Rewritten by Gary Houston to be a closer interface to the C socket library. + * Split into net_db.c and socket.c. + */ + + +#include <stdio.h> +#include "libguile/_scm.h" +#include "libguile/feature.h" +#include "libguile/strings.h" +#include "libguile/vectors.h" + +#include "libguile/validate.h" +#include "libguile/net_db.h" + +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +/* Some systems do not declare this. Some systems do declare it, as a + macro. */ +#ifndef h_errno +extern int h_errno; +#endif + + + +#ifndef STDC_HEADERS +int close (); +#endif /* STDC_HEADERS */ + +extern in_addr_t inet_aton (); + +SCM_DEFINE (scm_inet_aton, "inet-aton", 1, 0, 0, + (SCM address), + "Converts a string containing an Internet host address in the traditional\n" + "dotted decimal notation into an integer.\n\n" + "@smalllisp\n" + "(inet-aton \"127.0.0.1\") @result{} 2130706433\n\n" + "@end smalllisp") +#define FUNC_NAME s_scm_inet_aton +{ + struct in_addr soka; + + SCM_VALIDATE_ROSTRING (1,address); + if (SCM_SUBSTRP (address)) + address = scm_makfromstr (SCM_ROCHARS (address), SCM_ROLENGTH (address), 0); + if (inet_aton (SCM_ROCHARS (address), &soka) == 0) + SCM_MISC_ERROR ("bad address", SCM_EOL); + return scm_ulong2num (ntohl (soka.s_addr)); +} +#undef FUNC_NAME + + +SCM_DEFINE (scm_inet_ntoa, "inet-ntoa", 1, 0, 0, + (SCM inetid), + "Converts an integer Internet host address into a string with the\n" + "traditional dotted decimal representation.\n\n" + "@smalllisp\n" + "(inet-ntoa 2130706433) @result{} \"127.0.0.1\"" + "@end smalllisp") +#define FUNC_NAME s_scm_inet_ntoa +{ + struct in_addr addr; + char *s; + SCM answer; + addr.s_addr = htonl (SCM_NUM2ULONG (1,inetid)); + s = inet_ntoa (addr); + answer = scm_makfromstr (s, strlen (s), 0); + return answer; +} +#undef FUNC_NAME + +#ifdef HAVE_INET_NETOF +SCM_DEFINE (scm_inet_netof, "inet-netof", 1, 0, 0, + (SCM address), + "Returns the network number part of the given integer Internet address.\n\n" + "@smalllisp\n" + "(inet-netof 2130706433) @result{} 127\n" + "@end smalllisp") +#define FUNC_NAME s_scm_inet_netof +{ + struct in_addr addr; + addr.s_addr = htonl (SCM_NUM2ULONG (1,address)); + return scm_ulong2num ((unsigned long) inet_netof (addr)); +} +#undef FUNC_NAME +#endif + +#ifdef HAVE_INET_LNAOF +SCM_DEFINE (scm_lnaof, "inet-lnaof", 1, 0, 0, + (SCM address), + "Returns the local-address-with-network part of the given Internet\n" + "address.\n\n" + "@smalllisp\n" + "(inet-lnaof 2130706433) @result{} 1\n" + "@end smalllisp") +#define FUNC_NAME s_scm_lnaof +{ + struct in_addr addr; + addr.s_addr = htonl (SCM_NUM2ULONG (1,address)); + return scm_ulong2num ((unsigned long) inet_lnaof (addr)); +} +#undef FUNC_NAME +#endif + +#ifdef HAVE_INET_MAKEADDR +SCM_DEFINE (scm_inet_makeaddr, "inet-makeaddr", 2, 0, 0, + (SCM net, SCM lna), + "Makes an Internet host address by combining the network number @var{net}\n" + "with the local-address-within-network number @var{lna}.\n\n" + "@smalllisp\n" + "(inet-makeaddr 127 1) @result{} 2130706433\n" + "@end smalllisp") +#define FUNC_NAME s_scm_inet_makeaddr +{ + struct in_addr addr; + unsigned long netnum; + unsigned long lnanum; + +#if 0 /* GJB:FIXME:: */ + SCM_VALIDATE_INUM_COPY (1,net,netnum); + SCM_VALIDATE_INUM_COPY (2,lna,lnanum); +#else + netnum = SCM_NUM2ULONG (1, net); + lnanum = SCM_NUM2ULONG (2, lna); +#endif + addr = inet_makeaddr (netnum, lnanum); + return scm_ulong2num (ntohl (addr.s_addr)); +} +#undef FUNC_NAME +#endif + +SCM_SYMBOL (scm_host_not_found_key, "host-not-found"); +SCM_SYMBOL (scm_try_again_key, "try-again"); +SCM_SYMBOL (scm_no_recovery_key, "no-recovery"); +SCM_SYMBOL (scm_no_data_key, "no-data"); + +static void scm_resolv_error (const char *subr, SCM bad_value) +{ +#ifdef NETDB_INTERNAL + if (h_errno == NETDB_INTERNAL) + { + /* errno supposedly contains a useful value. */ + scm_syserror (subr); + } + else +#endif + { + SCM key; + const char *errmsg; + + switch (h_errno) + { + case HOST_NOT_FOUND: + key = scm_host_not_found_key; + errmsg = "Unknown host"; + break; + case TRY_AGAIN: + key = scm_try_again_key; + errmsg = "Host name lookup failure"; + break; + case NO_RECOVERY: + key = scm_no_recovery_key; + errmsg = "Unknown server error"; + break; + case NO_DATA: + key = scm_no_data_key; + errmsg = "No address associated with name"; + break; + default: + scm_misc_error (subr, "Unknown resolver error", SCM_EOL); + errmsg = NULL; + } + +#ifdef HAVE_HSTRERROR + errmsg = (const char *) hstrerror (h_errno); +#endif + scm_error (key, subr, errmsg, scm_cons (bad_value, SCM_EOL), SCM_EOL); + } +} + +/* Should take an extra arg for address format (will be needed for IPv6). + Should use reentrant facilities if available. + */ + +SCM_DEFINE (scm_gethost, "gethost", 0, 1, 0, + (SCM name), + "@deffnx procedure gethostbyname hostname\n" + "@deffnx procedure gethostbyaddr address\n" + "Look up a host by name or address, returning a host object. The\n" + "@code{gethost} procedure will accept either a string name or an integer\n" + "address; if given no arguments, it behaves like @code{gethostent} (see\n" + "below). If a name or address is supplied but the address can not be\n" + "found, an error will be thrown to one of the keys:\n" + "@code{host-not-found}, @code{try-again}, @code{no-recovery} or\n" + "@code{no-data}, corresponding to the equivalent @code{h_error} values.\n" + "Unusual conditions may result in errors thrown to the\n" + "@code{system-error} or @code{misc_error} keys.") +#define FUNC_NAME s_scm_gethost +{ + SCM ans = scm_make_vector (SCM_MAKINUM (5), SCM_UNSPECIFIED); + SCM *ve = SCM_VELTS (ans); + SCM lst = SCM_EOL; + struct hostent *entry; + struct in_addr inad; + char **argv; + int i = 0; + if (SCM_UNBNDP (name)) + { +#ifdef HAVE_GETHOSTENT + entry = gethostent (); +#else + entry = NULL; +#endif + if (! entry) + { + /* As far as I can tell, there's no good way to tell whether + zero means an error or end-of-file. The trick of + clearing errno before calling gethostent and checking it + afterwards doesn't cut it, because, on Linux, it seems to + try to contact some other server (YP?) and fails, which + is a benign failure. */ + return SCM_BOOL_F; + } + } + else if (SCM_ROSTRINGP (name)) + { + SCM_COERCE_SUBSTR (name); + entry = gethostbyname (SCM_ROCHARS (name)); + } + else + { + inad.s_addr = htonl (SCM_NUM2ULONG (1,name)); + entry = gethostbyaddr ((char *) &inad, sizeof (inad), AF_INET); + } + if (!entry) + scm_resolv_error (FUNC_NAME, name); + + ve[0] = scm_makfromstr (entry->h_name, + (scm_sizet) strlen (entry->h_name), 0); + ve[1] = scm_makfromstrs (-1, entry->h_aliases); + ve[2] = SCM_MAKINUM (entry->h_addrtype + 0L); + ve[3] = SCM_MAKINUM (entry->h_length + 0L); + if (sizeof (struct in_addr) != entry->h_length) + { + ve[4] = SCM_BOOL_F; + return ans; + } + for (argv = entry->h_addr_list; argv[i]; i++); + while (i--) + { + inad = *(struct in_addr *) argv[i]; + lst = scm_cons (scm_ulong2num (ntohl (inad.s_addr)), lst); + } + ve[4] = lst; + return ans; +} +#undef FUNC_NAME + + +/* In all subsequent getMUMBLE functions, when we're called with no + arguments, we're supposed to traverse the tables entry by entry. + However, there doesn't seem to be any documented way to distinguish + between end-of-table and an error; in both cases the functions + return zero. Gotta love Unix. For the time being, we clear errno, + and if we get a zero and errno is set, we signal an error. This + doesn't seem quite right (what if errno gets set as part of healthy + operation?), but it seems to work okay. We'll see. */ + +#if defined(HAVE_GETNETENT) && defined(HAVE_GETNETBYNAME) && defined(HAVE_GETNETBYADDR) +SCM_DEFINE (scm_getnet, "getnet", 0, 1, 0, + (SCM name), + "@deffnx procedure getnetbyname net-name\n" + "@deffnx procedure getnetbyaddr net-number\n" + "Look up a network by name or net number in the network database. The\n" + "@var{net-name} argument must be a string, and the @var{net-number}\n" + "argument must be an integer. @code{getnet} will accept either type of\n" + "argument, behaving like @code{getnetent} (see below) if no arguments are\n" + "given.") +#define FUNC_NAME s_scm_getnet +{ + SCM ans; + SCM *ve; + struct netent *entry; + + ans = scm_make_vector (SCM_MAKINUM (4), SCM_UNSPECIFIED); + ve = SCM_VELTS (ans); + if (SCM_UNBNDP (name)) + { + errno = 0; + entry = getnetent (); + if (! entry) + { + if (errno) + SCM_SYSERROR; + else + return SCM_BOOL_F; + } + } + else if (SCM_ROSTRINGP (name)) + { + SCM_COERCE_SUBSTR (name); + entry = getnetbyname (SCM_ROCHARS (name)); + } + else + { + unsigned long netnum; + netnum = SCM_NUM2ULONG (1, name); + entry = getnetbyaddr (netnum, AF_INET); + } + if (!entry) + SCM_SYSERROR_MSG ("no such network ~A", + scm_listify (name, SCM_UNDEFINED), errno); + ve[0] = scm_makfromstr (entry->n_name, (scm_sizet) strlen (entry->n_name), 0); + ve[1] = scm_makfromstrs (-1, entry->n_aliases); + ve[2] = SCM_MAKINUM (entry->n_addrtype + 0L); + ve[3] = scm_ulong2num (entry->n_net + 0L); + return ans; +} +#undef FUNC_NAME +#endif + +#ifdef HAVE_GETPROTOENT +SCM_DEFINE (scm_getproto, "getproto", 0, 1, 0, + (SCM name), + "@deffnx procedure getprotobyname name\n" + "@deffnx procedure getprotobynumber number\n" + "Look up a network protocol by name or by number. @code{getprotobyname}\n" + "takes a string argument, and @code{getprotobynumber} takes an integer\n" + "argument. @code{getproto} will accept either type, behaving like\n" + "@code{getprotoent} (see below) if no arguments are supplied.") +#define FUNC_NAME s_scm_getproto +{ + SCM ans; + SCM *ve; + struct protoent *entry; + + ans = scm_make_vector (SCM_MAKINUM (3), SCM_UNSPECIFIED); + ve = SCM_VELTS (ans); + if (SCM_UNBNDP (name)) + { + errno = 0; + entry = getprotoent (); + if (! entry) + { + if (errno) + SCM_SYSERROR; + else + return SCM_BOOL_F; + } + } + else if (SCM_ROSTRINGP (name)) + { + SCM_COERCE_SUBSTR (name); + entry = getprotobyname (SCM_ROCHARS (name)); + } + else + { + unsigned long protonum; + protonum = SCM_NUM2ULONG (1,name); + entry = getprotobynumber (protonum); + } + if (!entry) + SCM_SYSERROR_MSG ("no such protocol ~A", + scm_listify (name, SCM_UNDEFINED), errno); + ve[0] = scm_makfromstr (entry->p_name, (scm_sizet) strlen (entry->p_name), 0); + ve[1] = scm_makfromstrs (-1, entry->p_aliases); + ve[2] = SCM_MAKINUM (entry->p_proto + 0L); + return ans; +} +#undef FUNC_NAME +#endif + +static SCM +scm_return_entry (struct servent *entry) +{ + SCM ans; + SCM *ve; + + ans = scm_make_vector (SCM_MAKINUM (4), SCM_UNSPECIFIED); + ve = SCM_VELTS (ans); + ve[0] = scm_makfromstr (entry->s_name, (scm_sizet) strlen (entry->s_name), 0); + ve[1] = scm_makfromstrs (-1, entry->s_aliases); + ve[2] = SCM_MAKINUM (ntohs (entry->s_port) + 0L); + ve[3] = scm_makfromstr (entry->s_proto, (scm_sizet) strlen (entry->s_proto), 0); + return ans; +} + +#ifdef HAVE_GETSERVENT +SCM_DEFINE (scm_getserv, "getserv", 0, 2, 0, + (SCM name, SCM proto), + "@deffnx procedure getservbyname name protocol\n" + "@deffnx procedure getservbyport port protocol\n" + "Look up a network service by name or by service number, and return a\n" + "network service object. The @var{protocol} argument specifies the name\n" + "of the desired protocol; if the protocol found in the network service\n" + "database does not match this name, a system error is signalled.\n\n" + "The @code{getserv} procedure will take either a service name or number\n" + "as its first argument; if given no arguments, it behaves like\n" + "@code{getservent} (see below).") +#define FUNC_NAME s_scm_getserv +{ + struct servent *entry; + if (SCM_UNBNDP (name)) + { + errno = 0; + entry = getservent (); + if (!entry) + { + if (errno) + SCM_SYSERROR; + else + return SCM_BOOL_F; + } + return scm_return_entry (entry); + } + SCM_VALIDATE_ROSTRING (2,proto); + SCM_COERCE_SUBSTR (proto); + if (SCM_ROSTRINGP (name)) + { + SCM_COERCE_SUBSTR (name); + entry = getservbyname (SCM_ROCHARS (name), SCM_ROCHARS (proto)); + } + else + { + SCM_VALIDATE_INUM (1,name); + entry = getservbyport (htons (SCM_INUM (name)), SCM_ROCHARS (proto)); + } + if (!entry) + SCM_SYSERROR_MSG("no such service ~A", + scm_listify (name, SCM_UNDEFINED), errno); + return scm_return_entry (entry); +} +#undef FUNC_NAME +#endif + +#if defined(HAVE_SETHOSTENT) && defined(HAVE_ENDHOSTENT) +SCM_DEFINE (scm_sethost, "sethost", 0, 1, 0, + (SCM arg), + "If @var{stayopen} is omitted, this is equivalent to @code{endhostent}.\n" + "Otherwise it is equivalent to @code{sethostent stayopen}.") +#define FUNC_NAME s_scm_sethost +{ + if (SCM_UNBNDP (arg)) + endhostent (); + else + sethostent (SCM_NFALSEP (arg)); + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME +#endif + +#if defined(HAVE_SETNETENT) && defined(HAVE_ENDNETENT) +SCM_DEFINE (scm_setnet, "setnet", 0, 1, 0, + (SCM arg), + "If @var{stayopen} is omitted, this is equivalent to @code{endnetent}.\n" + "Otherwise it is equivalent to @code{setnetent stayopen}.") +#define FUNC_NAME s_scm_setnet +{ + if (SCM_UNBNDP (arg)) + endnetent (); + else + setnetent (SCM_NFALSEP (arg)); + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME +#endif + +#if defined(HAVE_SETPROTOENT) && defined(HAVE_ENDPROTOENT) +SCM_DEFINE (scm_setproto, "setproto", 0, 1, 0, + (SCM arg), + "If @var{stayopen} is omitted, this is equivalent to @code{endprotoent}.\n" + "Otherwise it is equivalent to @code{setprotoent stayopen}.") +#define FUNC_NAME s_scm_setproto +{ + if (SCM_UNBNDP (arg)) + endprotoent (); + else + setprotoent (SCM_NFALSEP (arg)); + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME +#endif + +#if defined(HAVE_SETSERVENT) && defined(HAVE_ENDSERVENT) +SCM_DEFINE (scm_setserv, "setserv", 0, 1, 0, + (SCM arg), + "If @var{stayopen} is omitted, this is equivalent to @code{endservent}.\n" + "Otherwise it is equivalent to @code{setservent stayopen}.") +#define FUNC_NAME s_scm_setserv +{ + if (SCM_UNBNDP (arg)) + endservent (); + else + setservent (SCM_NFALSEP (arg)); + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME +#endif + + +void +scm_init_net_db () +{ +#ifdef INADDR_ANY + scm_sysintern ("INADDR_ANY", scm_ulong2num (INADDR_ANY)); +#endif +#ifdef INADDR_BROADCAST + scm_sysintern ("INADDR_BROADCAST", scm_ulong2num (INADDR_BROADCAST)); +#endif +#ifdef INADDR_NONE + scm_sysintern ("INADDR_NONE", scm_ulong2num (INADDR_NONE)); +#endif +#ifdef INADDR_LOOPBACK + scm_sysintern ("INADDR_LOOPBACK", scm_ulong2num (INADDR_LOOPBACK)); +#endif + + scm_add_feature ("net-db"); +#include "libguile/net_db.x" +} + +/* + Local Variables: + c-file-style: "gnu" + End: +*/ diff --git a/dev-util/strace/files/stream.c b/dev-util/strace/files/stream.c new file mode 100644 index 000000000000..dd9b63397984 --- /dev/null +++ b/dev-util/strace/files/stream.c @@ -0,0 +1,810 @@ +/* + * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> + * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: stream.c,v 1.1 2000/11/15 16:46:05 achim Exp $ + */ + +#include "defs.h" + +#if defined(HAVE_SYS_STREAM_H) || defined(linux) + +#if defined(linux) +#include <sys/poll.h> +#include <stropts.h> +#define MORECTL 1 +#define MOREDATA 2 + +#else /* linux */ + +#include <stropts.h> + +#include <poll.h> +#include <sys/conf.h> +#include <sys/stream.h> +#include <sys/tihdr.h> + +#endif /* linux */ + +#ifdef HAVE_SYS_TIUSER_H +#include <sys/tiuser.h> +#include <sys/sockmod.h> +#include <sys/timod.h> +#endif /* HAVE_SYS_TIUSER_H */ + +static struct xlat msgflags[] = { + { RS_HIPRI, "RS_HIPRI" }, + { 0, NULL }, +}; + + +static void +printstrbuf(tcp, sbp, getting) +struct tcb *tcp; +struct strbuf *sbp; +int getting; +{ + if (sbp->maxlen == -1 && getting) + tprintf("{maxlen=-1}"); + else { + tprintf("{"); + if (getting) + tprintf("maxlen=%d, ", sbp->maxlen); + tprintf("len=%d, buf=", sbp->len); + printstr(tcp, (unsigned long) sbp->buf, sbp->len); + tprintf("}"); + } +} + +static void +printstrbufarg(tcp, arg, getting) +struct tcb *tcp; +int arg; +int getting; +{ + struct strbuf buf; + + if (arg == 0) + tprintf("NULL"); + else if (umove(tcp, arg, &buf) < 0) + tprintf("{...}"); + else + printstrbuf(tcp, &buf, getting); + tprintf(", "); +} + +int +sys_putmsg(tcp) +struct tcb *tcp; +{ + int i; + + if (entering(tcp)) { + /* fd */ + tprintf("%ld, ", tcp->u_arg[0]); + /* control and data */ + for (i = 1; i < 3; i++) + printstrbufarg(tcp, tcp->u_arg[i], 0); + /* flags */ + if (!printflags(msgflags, tcp->u_arg[3])) + tprintf("0"); + } + return 0; +} + +int +sys_getmsg(tcp) +struct tcb *tcp; +{ + int i, flags; + + if (entering(tcp)) { + /* fd */ + tprintf("%lu, ", tcp->u_arg[0]); + } else { + if (syserror(tcp)) { + tprintf("%#lx, %#lx, %#lx", + tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]); + return 0; + } + /* control and data */ + for (i = 1; i < 3; i++) + printstrbufarg(tcp, tcp->u_arg[i], 1); + /* pointer to flags */ + if (tcp->u_arg[3] == 0) + tprintf("NULL"); + else if (umove(tcp, tcp->u_arg[3], &flags) < 0) + tprintf("[?]"); + else { + tprintf("["); + if (!printflags(msgflags, flags)) + tprintf("0"); + tprintf("]"); + } + /* decode return value */ + switch (tcp->u_rval) { + case MORECTL: + tcp->auxstr = "MORECTL"; + break; + case MORECTL|MOREDATA: + tcp->auxstr = "MORECTL|MOREDATA"; + break; + case MOREDATA: + tcp->auxstr = "MORECTL"; + break; + default: + tcp->auxstr = NULL; + break; + } + } + return RVAL_HEX | RVAL_STR; +} + +#ifdef HAVE_PUTPMSG + +static struct xlat pmsgflags[] = { + { MSG_HIPRI, "MSG_HIPRI" }, + { MSG_ANY, "MSG_ANY" }, + { MSG_BAND, "MSG_BAND" }, + { 0, NULL }, +}; + +int +sys_putpmsg(tcp) +struct tcb *tcp; +{ + int i; + + if (entering(tcp)) { + /* fd */ + tprintf("%ld, ", tcp->u_arg[0]); + /* control and data */ + for (i = 1; i < 3; i++) + printstrbufarg(tcp, tcp->u_arg[i], 0); + /* band */ + tprintf("%ld, ", tcp->u_arg[3]); + /* flags */ + if (!printflags(pmsgflags, tcp->u_arg[4])) + tprintf("0"); + } + return 0; +} + +int +sys_getpmsg(tcp) +struct tcb *tcp; +{ + int i, flags; + + if (entering(tcp)) { + /* fd */ + tprintf("%lu, ", tcp->u_arg[0]); + } else { + if (syserror(tcp)) { + tprintf("%#lx, %#lx, %#lx, %#lx", tcp->u_arg[1], + tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[4]); + return 0; + } + /* control and data */ + for (i = 1; i < 3; i++) + printstrbufarg(tcp, tcp->u_arg[i], 1); + /* pointer to band */ + printnum(tcp, tcp->u_arg[3], "%d"); + tprintf(", "); + /* pointer to flags */ + if (tcp->u_arg[4] == 0) + tprintf("NULL"); + else if (umove(tcp, tcp->u_arg[4], &flags) < 0) + tprintf("[?]"); + else { + tprintf("["); + if (!printflags(pmsgflags, flags)) + tprintf("0"); + tprintf("]"); + } + /* decode return value */ + switch (tcp->u_rval) { + case MORECTL: + tcp->auxstr = "MORECTL"; + break; + case MORECTL|MOREDATA: + tcp->auxstr = "MORECTL|MOREDATA"; + break; + case MOREDATA: + tcp->auxstr = "MORECTL"; + break; + default: + tcp->auxstr = NULL; + break; + } + } + return RVAL_HEX | RVAL_STR; +} + +#endif /* HAVE_PUTPMSG */ + + +static struct xlat pollflags[] = { + { POLLIN, "POLLIN" }, + { POLLPRI, "POLLPRI" }, + { POLLOUT, "POLLOUT" }, +#ifdef POLLRDNORM + { POLLRDNORM, "POLLRDNORM" }, +#endif +#ifdef POLLWRNORM + { POLLWRNORM, "POLLWRNORM" }, +#endif +#ifdef POLLRDBAND + { POLLRDBAND, "POLLRDBAND" }, +#endif +#ifdef POLLWRBAND + { POLLWRBAND, "POLLWRBAND" }, +#endif + { POLLERR, "POLLERR" }, + { POLLHUP, "POLLHUP" }, + { POLLNVAL, "POLLNVAL" }, + { 0, NULL }, +}; + +int +sys_poll(tcp) +struct tcb *tcp; +{ + struct pollfd *pollp; + + if (exiting(tcp)) { + int i; + int nfds = tcp->u_arg[1]; + + if (nfds <= 0) { + tprintf("%#lx, %d, %ld\n", + tcp->u_arg[0], nfds, tcp->u_arg[2]); + return 0; + } + pollp = (struct pollfd *) malloc(nfds * sizeof(*pollp)); + if (pollp == NULL) { + fprintf(stderr, "sys_poll: no memory\n"); + tprintf("%#lx, %d, %ld", + tcp->u_arg[0], nfds, tcp->u_arg[2]); + return 0; + } + if (umoven(tcp, tcp->u_arg[0], + (nfds * sizeof(*pollp)), (char *) pollp) < 0) { + tprintf("%#lx", tcp->u_arg[0]); + } + else { + tprintf("["); + for (i = 0; i < nfds; i++) { + if (i) + tprintf(", "); + if (pollp[i].fd < 0) { + tprintf("{fd=%d}", pollp[i].fd); + continue; + } + tprintf("{fd=%d, events=", pollp[i].fd); + if (!printflags(pollflags, pollp[i].events)) + tprintf("0"); + if (!syserror(tcp) && pollp[i].revents) { + tprintf(", revents="); + if (!printflags(pollflags, + pollp[i].revents)) + tprintf("0"); + } + tprintf("}"); + } + tprintf("]"); + } + tprintf(", %d, ", nfds); +#ifdef INFTIM + if (tcp->u_arg[2] == INFTIM) + tprintf("INFTIM"); + else +#endif + tprintf("%ld", tcp->u_arg[2]); + free(pollp); + } + return 0; +} + +#ifndef linux + +static struct xlat stream_flush_options[] = { + { FLUSHR, "FLUSHR" }, + { FLUSHW, "FLUSHW" }, + { FLUSHRW, "FLUSHRW" }, +#ifdef FLUSHBAND + { FLUSHBAND, "FLUSHBAND" }, +#endif + { 0, NULL }, +}; + +static struct xlat stream_setsig_flags[] = { + { S_INPUT, "S_INPUT" }, + { S_HIPRI, "S_HIPRI" }, + { S_OUTPUT, "S_OUTPUT" }, + { S_MSG, "S_MSG" }, +#ifdef S_ERROR + { S_ERROR, "S_ERROR" }, +#endif +#ifdef S_HANGUP + { S_HANGUP, "S_HANGUP" }, +#endif +#ifdef S_RDNORM + { S_RDNORM, "S_RDNORM" }, +#endif +#ifdef S_WRNORM + { S_WRNORM, "S_WRNORM" }, +#endif +#ifdef S_RDBAND + { S_RDBAND, "S_RDBAND" }, +#endif +#ifdef S_WRBAND + { S_WRBAND, "S_WRBAND" }, +#endif +#ifdef S_BANDURG + { S_BANDURG, "S_BANDURG" }, +#endif + { 0, NULL }, +}; + +static struct xlat stream_read_options[] = { + { RNORM, "RNORM" }, + { RMSGD, "RMSGD" }, + { RMSGN, "RMSGN" }, + { 0, NULL }, +}; + +static struct xlat stream_read_flags[] = { +#ifdef RPROTDAT + { RPROTDAT, "RPROTDAT" }, +#endif +#ifdef RPROTDIS + { RPROTDIS, "RPROTDIS" }, +#endif +#ifdef RPROTNORM + { RPROTNORM, "RPROTNORM" }, +#endif + { 0, NULL }, +}; + +#ifndef RMODEMASK +#define RMODEMASK (~0) +#endif + +#ifdef I_SWROPT +static struct xlat stream_write_flags[] = { + { SNDZERO, "SNDZERO" }, + { SNDPIPE, "SNDPIPE" }, + { 0, NULL }, +}; +#endif /* I_SWROPT */ + +#ifdef I_ATMARK +static struct xlat stream_atmark_options[] = { + { ANYMARK, "ANYMARK" }, + { LASTMARK, "LASTMARK" }, + { 0, NULL }, +}; +#endif /* I_ATMARK */ + +#ifdef TI_BIND +static struct xlat transport_user_options[] = { + { T_CONN_REQ, "T_CONN_REQ" }, + { T_CONN_RES, "T_CONN_RES" }, + { T_DISCON_REQ, "T_DISCON_REQ" }, + { T_DATA_REQ, "T_DATA_REQ" }, + { T_EXDATA_REQ, "T_EXDATA_REQ" }, + { T_INFO_REQ, "T_INFO_REQ" }, + { T_BIND_REQ, "T_BIND_REQ" }, + { T_UNBIND_REQ, "T_UNBIND_REQ" }, + { T_UNITDATA_REQ,"T_UNITDATA_REQ"}, + { T_OPTMGMT_REQ,"T_OPTMGMT_REQ" }, + { T_ORDREL_REQ, "T_ORDREL_REQ" }, + { 0, NULL }, +}; + +static struct xlat transport_provider_options[] = { + { T_CONN_IND, "T_CONN_IND" }, + { T_CONN_CON, "T_CONN_CON" }, + { T_DISCON_IND, "T_DISCON_IND" }, + { T_DATA_IND, "T_DATA_IND" }, + { T_EXDATA_IND, "T_EXDATA_IND" }, + { T_INFO_ACK, "T_INFO_ACK" }, + { T_BIND_ACK, "T_BIND_ACK" }, + { T_ERROR_ACK, "T_ERROR_ACK" }, + { T_OK_ACK, "T_OK_ACK" }, + { T_UNITDATA_IND,"T_UNITDATA_IND"}, + { T_UDERROR_IND,"T_UDERROR_IND" }, + { T_OPTMGMT_ACK,"T_OPTMGMT_ACK" }, + { T_ORDREL_IND, "T_ORDREL_IND" }, + { 0, NULL }, +}; +#endif /* TI_BIND */ + +static int +internal_stream_ioctl(tcp, arg) +struct tcb *tcp; +int arg; +{ + struct strioctl si; + char *name; + int in_and_out; +#ifdef SI_GETUDATA + struct si_udata udata; +#endif /* SI_GETUDATA */ + + if (!arg) + return 0; + if (umove(tcp, arg, &si) < 0) { + if (entering(tcp)) + tprintf(", {...}"); + return 1; + } + if (entering(tcp)) { + name = ioctl_lookup(si.ic_cmd); + if (name) + tprintf(", {ic_cmd=%s", name); + else + tprintf(", {ic_cmd=%#x", si.ic_cmd); + if (si.ic_timout == INFTIM) + tprintf(", ic_timout=INFTIM, "); + else + tprintf(" ic_timout=%d, ", si.ic_timout); + } + in_and_out = 1; + switch (si.ic_cmd) { +#ifdef SI_GETUDATA + case SI_GETUDATA: + in_and_out = 0; + break; +#endif /* SI_GETUDATA */ + } + if (in_and_out) { + if (entering(tcp)) + tprintf("/* in */ "); + else + tprintf(", /* out */ "); + } + if (in_and_out || entering(tcp)) + tprintf("ic_len=%d, ic_dp=", si.ic_len); + switch (si.ic_cmd) { +#ifdef TI_BIND + case TI_BIND: + /* in T_BIND_REQ, out T_BIND_ACK */ + if (entering(tcp)) { + struct T_bind_req data; + +#if 0 + tprintf("struct T_bind_req "); +#endif + if (umove(tcp, (int) si.ic_dp, &data) < 0) + tprintf("{...}"); + else { + tprintf("{PRIM_type="); + printxval(transport_user_options, + data.PRIM_type, "T_???"); + tprintf(", ADDR_length=%ld, ADDR_offset=%ld", + data.ADDR_length, data.ADDR_offset); + tprintf(", CONIND_number=%ld}", + data.CONIND_number); + } + } + else { + struct T_bind_ack data; + +#if 0 + tprintf("struct T_bind_ack "); +#endif + if (umove(tcp, (int) si.ic_dp, &data) < 0) + tprintf("{...}"); + else { + tprintf("["); + tprintf("{PRIM_type="); + printxval(transport_provider_options, + data.PRIM_type, "T_???"); + tprintf(", ADDR_length=%ld, ADDR_offset=%ld", + data.ADDR_length, data.ADDR_offset); + tprintf(", CONIND_number=%ld}", + data.CONIND_number); + tprintf(", "); + printstr(tcp, + (int) si.ic_dp + data.ADDR_offset, + data.ADDR_length); + tprintf("]"); + } + } + break; +#endif /* TI_BIND */ +#if 0 +#ifdef TI_UNBIND + case TI_UNBIND: + /* in T_UNBIND_REQ, out T_OK_ACK */ + break; +#endif /* TI_UNBIND */ +#ifdef TI_GETINFO + case TI_GETINFO: + /* in T_INFO_REQ, out T_INFO_ACK */ + break; +#endif /* TI_GETINFO */ +#ifdef TI_OPTMGMT + case TI_OPTMGMT: + /* in T_OPTMGMT_REQ, out T_OPTMGMT_ACK */ + break; +#endif /* TI_OPTMGMT */ +#endif +#ifdef SI_GETUDATA + case SI_GETUDATA: + if (entering(tcp)) + break; +#if 0 + tprintf("struct si_udata "); +#endif + if (umove(tcp, (int) si.ic_dp, &udata) < 0) + tprintf("{...}"); + else { + tprintf("{tidusize=%d, addrsize=%d, ", + udata.tidusize, udata.addrsize); + tprintf("optsize=%d, etsdusize=%d, ", + udata.optsize, udata.etsdusize); + tprintf("servtype=%d, so_state=%d, ", + udata.servtype, udata.so_state); + tprintf("so_options=%d", udata.so_options); +#if 0 + tprintf(", tsdusize=%d", udata.tsdusize); +#endif + tprintf("}"); + } + break; +#endif /* SI_GETUDATA */ + default: + printstr(tcp, (int) si.ic_dp, si.ic_len); + break; + } + if (exiting(tcp)) + tprintf("}"); + return 1; +} + +int +stream_ioctl(tcp, code, arg) +struct tcb *tcp; +int code, arg; +{ +#ifdef I_LIST + int i; +#endif + int val; +#ifdef I_FLUSHBAND + struct bandinfo bi; +#endif + struct strpeek sp; + struct strfdinsert sfi; + struct strrecvfd srf; +#ifdef I_LIST + struct str_list sl; +#endif + + /* I_STR is a special case because the data is read & written. */ + if (code == I_STR) + return internal_stream_ioctl(tcp, arg); + if (entering(tcp)) + return 0; + + switch (code) { + case I_PUSH: + case I_LOOK: + case I_FIND: + /* arg is a string */ + tprintf(", "); + printpath(tcp, arg); + return 1; + case I_POP: + /* doesn't take an argument */ + return 1; + case I_FLUSH: + /* argument is an option */ + tprintf(", "); + printxval(stream_flush_options, arg, "FLUSH???"); + return 1; +#ifdef I_FLUSHBAND + case I_FLUSHBAND: + /* argument is a pointer to a bandinfo struct */ + if (umove(tcp, arg, &bi) < 0) + tprintf(", {...}"); + else { + tprintf(", {bi_pri=%d, bi_flag=", bi.bi_pri); + if (!printflags(stream_flush_options, bi.bi_flag)) + tprintf("0"); + tprintf("}"); + } + return 1; +#endif /* I_FLUSHBAND */ + case I_SETSIG: + /* argument is a set of flags */ + tprintf(", "); + if (!printflags(stream_setsig_flags, arg)) + tprintf("0"); + return 1; + case I_GETSIG: + /* argument is a pointer to a set of flags */ + if (syserror(tcp)) + return 0; + tprintf(", ["); + if (umove(tcp, arg, &val) < 0) + tprintf("?"); + else if (!printflags(stream_setsig_flags, val)) + tprintf("0"); + tprintf("]"); + return 1; + case I_PEEK: + /* argument is a pointer to a strpeek structure */ + if (syserror(tcp) || !arg) + return 0; + if (umove(tcp, arg, &sp) < 0) { + tprintf(", {...}"); + return 1; + } + tprintf(", {ctlbuf="); + printstrbuf(tcp, &sp.ctlbuf, 1); + tprintf(", databuf="); + printstrbuf(tcp, &sp.databuf, 1); + if (!printflags(msgflags, sp.flags)) + tprintf("0"); + return 1; + case I_SRDOPT: + /* argument is an option with flags */ + tprintf(", "); + printxval(stream_read_options, arg & RMODEMASK, "R???"); + addflags(stream_read_flags, arg & ~RMODEMASK); + return 1; + case I_GRDOPT: + /* argument is an pointer to an option with flags */ + if (syserror(tcp)) + return 0; + tprintf(", ["); + if (umove(tcp, arg, &val) < 0) + tprintf("?"); + else { + printxval(stream_read_options, + arg & RMODEMASK, "R???"); + addflags(stream_read_flags, arg & ~RMODEMASK); + } + tprintf("]"); + return 1; + case I_NREAD: +#ifdef I_GETBAND + case I_GETBAND: +#endif +#ifdef I_SETCLTIME + case I_SETCLTIME: +#endif +#ifdef I_GETCLTIME + case I_GETCLTIME: +#endif + /* argument is a pointer to a decimal integer */ + if (syserror(tcp)) + return 0; + tprintf(", "); + printnum(tcp, arg, "%d"); + return 1; + case I_FDINSERT: + /* argument is a pointer to a strfdinsert structure */ + if (syserror(tcp) || !arg) + return 0; + if (umove(tcp, arg, &sfi) < 0) { + tprintf(", {...}"); + return 1; + } + tprintf(", {ctlbuf="); + printstrbuf(tcp, &sfi.ctlbuf, 1); + tprintf(", databuf="); + printstrbuf(tcp, &sfi.databuf, 1); + if (!printflags(msgflags, sfi.flags)) + tprintf("0"); + tprintf(", filedes=%d, offset=%d}", sfi.fildes, sfi.offset); + return 1; +#ifdef I_SWROPT + case I_SWROPT: + /* argument is a set of flags */ + tprintf(", "); + if (!printflags(stream_write_flags, arg)) + tprintf("0"); + return 1; +#endif /* I_SWROPT */ +#ifdef I_GWROPT + case I_GWROPT: + /* argument is an pointer to an option with flags */ + if (syserror(tcp)) + return 0; + tprintf(", ["); + if (umove(tcp, arg, &val) < 0) + tprintf("?"); + else if (!printflags(stream_write_flags, arg)) + tprintf("0"); + tprintf("]"); + return 1; +#endif /* I_GWROPT */ + case I_SENDFD: +#ifdef I_CKBAND + case I_CKBAND: +#endif +#ifdef I_CANPUT + case I_CANPUT: +#endif + case I_LINK: + case I_UNLINK: + case I_PLINK: + case I_PUNLINK: + /* argument is a decimal integer */ + tprintf(", %d", arg); + return 1; + case I_RECVFD: + /* argument is a pointer to a strrecvfd structure */ + if (syserror(tcp) || !arg) + return 0; + if (umove(tcp, arg, &srf) < 0) { + tprintf(", {...}"); + return 1; + } + tprintf(", {fd=%d, uid=%lu, gid=%lu}", srf.fd, + (unsigned long) srf.uid, (unsigned long) srf.gid); + return 1; +#ifdef I_LIST + case I_LIST: + if (syserror(tcp)) + return 0; + if (arg == 0) { + tprintf(", NULL"); + return 1; + } + if (umove(tcp, arg, &sl) < 0) { + tprintf(", {...}"); + return 1; + } + tprintf(", {sl_nmods=%d, sl_modlist=[", sl.sl_nmods); + for (i = 0; i < tcp->u_rval; i++) { + if (i) + tprintf(", "); + printpath(tcp, (int) sl.sl_modlist[i].l_name); + } + tprintf("]}"); + return 1; +#endif /* I_LIST */ +#ifdef I_ATMARK + case I_ATMARK: + tprintf(", "); + printxval(stream_atmark_options, arg, "???MARK"); + return 1; +#endif /* I_ATMARK */ + default: + return 0; + } +} + +#endif /* linux */ + +#endif /* LINUXSPARC && linux */ + |