update from main archive 961109

Sun Nov 10 02:37:15 1996  Ulrich Drepper  <drepper@cygnus.com>

	* inet/gethstent_r.c: Update copyright.
	* nss/getXXbyYY_r.c: Likewise.
	* nss/nsswitch.c: Likewise.
	* nss/getXXent_r.c: Likewise.
	* nss/nss_files/files-XXX.c: Likewise.
	* nss/nss_files/files-netgroup.c: Likewise.
	* nss/nss_files/files-parse.c: Likewise.

	* nss/getXXent_r.c: Change implementation.  It's not necessary to
	call all setXXent functions.  Just find first available and
	when necessary let getXXent_r call the others.

	* nss/nss_files/files-XXX.c: Make really reentrant.  Now calls
	of getXXent and getXXbyYY can be mixed.  The cursor for traversing
	the database with getXXent will be remembered.

	* stdlib/test-canon.c (cwd): Change size to PATH_MAX.

Sat Nov  9 15:34:48 1996  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/unix/sysv/linux/Dist: Add sys/mtio.h.
	* sysdeps/unix/sysv/linux/sys/mtio.h: New file.

	* signal/signal.h [__USE_BSD]: Add prototype for siggetmask.

Fri Nov  8 13:29:30 1996  Ulrich Drepper  <drepper@cygnus.com>

	* ctype/ctype.h (__isascii): Don't test for seventh bit not to be
	set.  Instead for none beside the first seven bits to be set.
	X/Open allows the argument to be an `int' value.
	Reported by Alain Williams <addw@phcomp.co.uk>.
	(toascii, isascii): Define macro also when __USE_XOPEN.

	* sysdeps/posix/fpathconf.c: Use fstatfs to compute NAME_MAX, not
	PATH_MAX.

Thu Nov  7 03:04:29 1996  Ulrich Drepper  <drepper@cygnus.com>

	* nss/getXXXent_r.c (SETFUNC_NAME): Reset `nip' after loop to
	NULL so that GETFUNC will see first entry.
	(ENDFUNC_NAME): Likewise.

	Rewrite Netgroups implementation to avoid global data.
	* inet/netgroup.h: Add definition of name_list and struct
	__netgrent.
	Add prototypes for internal netgroup functions.
	* nss/nss_files/files-netgroup.c (_nss_files_setnetgrent): Take
	extra argument and use the included data instead of global vars.
	(_nss_files_endnetgrent): Likewise.
	(_nss_netgroup_parseline): Change to be static and use data
	included in the RESULT structure.
	* inet/getnetgrent_r.c (startp): Move into setup function.
	(known_groups, needed_groups): new part of the __netgrent sruct.
	(freememory): Take extra argument and use included data.
	(__internal_endnetgrent): Likewise.
	(internal_setnetgrent): Renamed to __internal_setnetgrent_reuse
	and take extra argument.
	(__internal_setnetgrent): New function.  Call
	__internal_setnetgrent_reuse after calling free_memory.
	(setnetgrent): Only call __internal_setnetgrent.
	(__getnetgrent_r): Split into two functions.  __getnetgrent_r
	calls __internal_getnetgrent after locking.
	(innetgr): Use dynamic data only.  I.e., innetgr now is fully
	reentrant.

Thu Nov  7 00:15:14 1996  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/stub/setenv.c: Correct typo: unseenv -> unsetenv.
	Reported by Joshua Cowan <jcowan@jcowan.reslife.okstate.edu>.

Wed Nov  6 13:13:37 1996  Ulrich Drepper  <drepper@cygnus.com>

	* manual/creature.texi: Document that _GNU_SOURCE is no longer the
	default when no *_SOURCE macro is given.
	Reported by Karsten Weiss <karsten@addx.au.s.shuttle.de>.
	* NOTES: remade from manual/creature.texi.
	* manual/libc.texinfo: Add back line about GPL translation which
	somehow got lost.

	* Make-dist (dist.tar): Depend on README being updated.

	* rellns-sh: Correct thinko in removing leading /.
	Reported by Andreas Jaeger <aj@arthur.pfalz.de>.

	* pwd/fgetpwent_r.c: Recognize lines containing only names starting
	with `+' or `-' in parser.
	* grp/fgetgrent_r.c: Likewise.
	* shadow/sgetspent_r.c: Likewise.
	* nss/nss_files/files-spwd.c: Don't accept entries starting with
	`+' or `-'.

	* sysdeps/stub/lchown.c: New file.
This commit is contained in:
Ulrich Drepper 1996-11-10 02:21:51 +00:00
parent fe92af1832
commit 2303f5fdd9
26 changed files with 613 additions and 319 deletions

View File

@ -1,3 +1,96 @@
Sun Nov 10 02:37:15 1996 Ulrich Drepper <drepper@cygnus.com>
* inet/gethstent_r.c: Update copyright.
* nss/getXXbyYY_r.c: Likewise.
* nss/nsswitch.c: Likewise.
* nss/getXXent_r.c: Likewise.
* nss/nss_files/files-XXX.c: Likewise.
* nss/nss_files/files-netgroup.c: Likewise.
* nss/nss_files/files-parse.c: Likewise.
* nss/getXXent_r.c: Change implementation. It's not necessary to
call all setXXent functions. Just find first available and
when necessary let getXXent_r call the others.
* nss/nss_files/files-XXX.c: Make really reentrant. Now calls
of getXXent and getXXbyYY can be mixed. The cursor for traversing
the database with getXXent will be remembered.
* stdlib/test-canon.c (cwd): Change size to PATH_MAX.
Sat Nov 9 15:34:48 1996 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/unix/sysv/linux/Dist: Add sys/mtio.h.
* sysdeps/unix/sysv/linux/sys/mtio.h: New file.
* signal/signal.h [__USE_BSD]: Add prototype for siggetmask.
Fri Nov 8 13:29:30 1996 Ulrich Drepper <drepper@cygnus.com>
* ctype/ctype.h (__isascii): Don't test for seventh bit not to be
set. Instead for none beside the first seven bits to be set.
X/Open allows the argument to be an `int' value.
Reported by Alain Williams <addw@phcomp.co.uk>.
(toascii, isascii): Define macro also when __USE_XOPEN.
* sysdeps/posix/fpathconf.c: Use fstatfs to compute NAME_MAX, not
PATH_MAX.
Thu Nov 7 03:04:29 1996 Ulrich Drepper <drepper@cygnus.com>
* nss/getXXXent_r.c (SETFUNC_NAME): Reset `nip' after loop to
NULL so that GETFUNC will see first entry.
(ENDFUNC_NAME): Likewise.
Rewrite Netgroups implementation to avoid global data.
* inet/netgroup.h: Add definition of name_list and struct
__netgrent.
Add prototypes for internal netgroup functions.
* nss/nss_files/files-netgroup.c (_nss_files_setnetgrent): Take
extra argument and use the included data instead of global vars.
(_nss_files_endnetgrent): Likewise.
(_nss_netgroup_parseline): Change to be static and use data
included in the RESULT structure.
* inet/getnetgrent_r.c (startp): Move into setup function.
(known_groups, needed_groups): new part of the __netgrent sruct.
(freememory): Take extra argument and use included data.
(__internal_endnetgrent): Likewise.
(internal_setnetgrent): Renamed to __internal_setnetgrent_reuse
and take extra argument.
(__internal_setnetgrent): New function. Call
__internal_setnetgrent_reuse after calling free_memory.
(setnetgrent): Only call __internal_setnetgrent.
(__getnetgrent_r): Split into two functions. __getnetgrent_r
calls __internal_getnetgrent after locking.
(innetgr): Use dynamic data only. I.e., innetgr now is fully
reentrant.
Thu Nov 7 00:15:14 1996 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/stub/setenv.c: Correct typo: unseenv -> unsetenv.
Reported by Joshua Cowan <jcowan@jcowan.reslife.okstate.edu>.
Wed Nov 6 13:13:37 1996 Ulrich Drepper <drepper@cygnus.com>
* manual/creature.texi: Document that _GNU_SOURCE is no longer the
default when no *_SOURCE macro is given.
Reported by Karsten Weiss <karsten@addx.au.s.shuttle.de>.
* NOTES: remade from manual/creature.texi.
* manual/libc.texinfo: Add back line about GPL translation which
somehow got lost.
* Make-dist (dist.tar): Depend on README being updated.
* rellns-sh: Correct thinko in removing leading /.
Reported by Andreas Jaeger <aj@arthur.pfalz.de>.
* pwd/fgetpwent_r.c: Recognize lines containing only names starting
with `+' or `-' in parser.
* grp/fgetgrent_r.c: Likewise.
* shadow/sgetspent_r.c: Likewise.
* nss/nss_files/files-spwd.c: Don't accept entries starting with
`+' or `-'.
Wed Nov 6 04:30:26 1996 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/unix/sysv/linux/syscalls.list: Add weak alias llseek for
@ -19,6 +112,7 @@ Tue Nov 5 23:38:28 1996 Ulrich Drepper <drepper@cygnus.com>
if __USE_XOPEN_EXTENDED is defined.
* io/Makefile (routines): Add lchown.
* sysdeps/stub/lchown.c: New file.
* io/sys/poll.h: Add definition of POLLWRNORM.

View File

@ -191,7 +191,7 @@ configure: configure.in aclocal.m4; $(autoconf-it)
dist: $(tardir).tar.gz
subdir_dist: dist.tar
dist.tar: $(tardir) $(+tsrcs)
dist.tar: README $(tardir) $(+tsrcs)
tar chvf $@ $(addprefix $(tardir)/,$(filter-out $(tardir),$^))
$(tardir).tar: dist.tar subdir_dist

36
NOTES
View File

@ -53,12 +53,26 @@ self-contained way.
- Macro: _SVID_SOURCE
If you define this macro, functionality derived from SVID is
included as well as the ANSI C, POSIX.1, and POSIX.2 material.
included as well as the ANSI C, POSIX.1, POSIX.2, and X/Open
material.
- Macro: _XOPEN_SOURCE
If you define these macro, functionality described in the X/Open
Portability Guide is included. This is an superset of the POSIX.1
and POSIX.2 functionality and in fact `_POSIX_SOURCE' and
`_POSIX_C_SOURCE' get automatically be defined.
But as the great unifaction of all Unices there is also
functionality only available in BSD and SVID is included.
If the macro `_XOPEN_SOURCE_EXTENDED' is also defined, even more
functionality is available. The extra functions will make all
functions available which are necessary for the X/Open Unix brand.
- Macro: _GNU_SOURCE
If you define this macro, everything is included: ANSI C, POSIX.1,
POSIX.2, BSD, SVID, and GNU extensions. In the cases where POSIX.1
conflicts with BSD, the POSIX definitions take precedence.
POSIX.2, BSD, SVID, X/Open, and GNU extensions. In the cases where
POSIX.1 conflicts with BSD, the POSIX definitions take precedence.
If you want to get the full effect of `_GNU_SOURCE' but make the
BSD definitions take precedence over the POSIX definitions, use
@ -73,9 +87,23 @@ self-contained way.
compiler or linker. *Note:* If you forget to do this, you may get
very strange errors at run time.
- Macro: _REENTRANT,_THREAD_SAFE
If you define one this macro, reentrant versions of several
functions get declared. Some of the functions are specified in
POSIX.1c but many others are only available on a few other systems
or are unique to GNU libc. The problem is that the
standardization of the thread safe C library interface still is
behind.
Unlike on some other systems no special version of the C library
must be used for linking. There is only one version but while
compiling this it must have been specified to compile as thread
safe.
We recommend you use `_GNU_SOURCE' in new programs. If you don't
specify the `-ansi' option to GCC and don't define any of these macros
explicitly, the effect is the same as defining `_GNU_SOURCE'.
explicitly, the effect is the same as defining `_POSIX_C_SOURCE' to 2
and `_POSIX_SOURCE', `_SVID_SOURCE', and `_BSD_SOURCE' to 1.
When you define a feature test macro to request a larger class of
features, it is harmless to define in addition a feature test macro for

View File

@ -78,8 +78,8 @@ extern __const int *__ctype_toupper; /* Case conversions. */
#define __isctype(c, type) \
(__ctype_b[(int) (c)] & (unsigned short int) type)
#define __isascii(c) (((c) & (1 << 7)) == 0) /* If high bit is set. */
#define __toascii(c) ((c) & 0x7f) /* Mask off high bit. */
#define __isascii(c) (((c) & ~0x7f) == 0) /* If C is a 7 bit value. */
#define __toascii(c) ((c) & 0x7f) /* Mask off high bits. */
#define __tolower(c) ((int) __ctype_tolower[(int) (c)])
#define __toupper(c) ((int) __ctype_toupper[(int) (c)])
@ -126,7 +126,7 @@ extern int toascii __P ((int __c));
#endif /* Use SVID or use misc. */
#if defined(__USE_SVID) || defined(__USE_XOPEN)
#if defined(__USE_SVID) || defined(__USE_MISC) || defined(__USE_XOPEN)
/* These are the same as `toupper' and `tolower'. */
__exctype (_toupper);
__exctype (_tolower);
@ -152,7 +152,7 @@ __exctype (_tolower);
#define tolower(c) __tolower(c)
#define toupper(c) __toupper(c)
#if defined(__USE_SVID) || defined(__USE_MISC)
#if defined(__USE_SVID) || defined(__USE_MISC) || defined(__USE_XOPEN)
#define isascii(c) __isascii(c)
#define toascii(c) __toascii(c)
#endif

View File

@ -12,9 +12,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include <grp.h>
@ -33,11 +33,20 @@ struct grent_data {};
LINE_PARSER
(,
STRING_FIELD (result->gr_name, ISCOLON, 0);
if (line[0] == '\0'
&& (result->gr_name[0] == '+' || result->gr_name[0] == '-'))
{
result->gr_passwd = NULL;
result->gr_gid = 0;
}
else
{
STRING_FIELD (result->gr_passwd, ISCOLON, 0);
if (result->gr_name[0] == '+' || result->gr_name[0] == '-')
INT_FIELD_MAYBE_NULL (result->gr_gid, ISCOLON, 0, 10, , 0)
else
INT_FIELD (result->gr_gid, ISCOLON, 0, 10,)
}
)

View File

@ -12,8 +12,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <netdb.h>

View File

@ -18,6 +18,7 @@ Boston, MA 02111-1307, USA. */
#include <libc-lock.h>
#include <netdb.h>
#include <string.h>
#include "netgroup.h"
#include "nsswitch.h"
@ -28,18 +29,10 @@ __libc_lock_define_initialized (static, lock)
/* This handle for the NSS data base is shared between all
set/get/endXXXent functions. */
static service_user *nip;
/* Remember the first service_entry, it's always the same. */
static service_user *startp;
/* A netgroup can consist of names of other netgroups. We have to
track which netgroups were read and which still have to be read. */
struct name_list
{
const char *name;
struct name_list *next;
};
struct name_list *known_groups;
struct name_list *needed_groups;
/* The whole information for the set/get/endnetgrent functions are
kept in this structure. */
static struct __netgrent dataset;
/* The lookup function for the first entry of this service. */
@ -52,7 +45,10 @@ extern int __nss_netgroup_lookup (service_user **nip, const char *name,
static enum nss_status
setup (void **fctp, const char *func_name, int all)
{
/* Remember the first service_entry, it's always the same. */
static service_user *startp = NULL;
int no_more;
if (startp == NULL)
{
no_more = __nss_netgroup_lookup (&nip, func_name, fctp);
@ -74,29 +70,29 @@ setup (void **fctp, const char *func_name, int all)
/* Free used memory. */
static void
free_memory (void)
free_memory (struct __netgrent *data)
{
while (known_groups != NULL)
while (data->known_groups != NULL)
{
struct name_list *tmp = known_groups;
known_groups = known_groups->next;
struct name_list *tmp = data->known_groups;
data->known_groups = data->known_groups->next;
free (tmp->name);
free (tmp);
}
while (needed_groups != NULL)
while (data->needed_groups != NULL)
{
struct name_list *tmp = needed_groups;
needed_groups = needed_groups->next;
struct name_list *tmp = data->needed_groups;
data->needed_groups = data->needed_groups->next;
free (tmp->name);
free (tmp);
}
}
static int
internal_setnetgrent (const char *group)
__internal_setnetgrent_reuse (const char *group, struct __netgrent *datap)
{
enum nss_status (*fct) (const char *);
enum nss_status (*fct) (const char *, struct __netgrent *);
enum nss_status status = NSS_STATUS_UNAVAIL;
struct name_list *new_elem;
int no_more;
@ -106,7 +102,7 @@ internal_setnetgrent (const char *group)
while (! no_more)
{
/* Ignore status, we force check in `__nss_next'. */
status = (*fct) (group);
status = (*fct) (group, datap);
no_more = __nss_next (&nip, "setnetgrent", (void **) &fct, status, 0);
}
@ -121,13 +117,22 @@ internal_setnetgrent (const char *group)
}
else
{
new_elem->next = known_groups;
known_groups = new_elem;
new_elem->next = datap->known_groups;
datap->known_groups = new_elem;
}
return status == NSS_STATUS_SUCCESS;
}
int
__internal_setnetgrent (const char *group, struct __netgrent *datap)
{
/* Free list of all netgroup names from last run. */
free_memory (datap);
return __internal_setnetgrent_reuse (group, datap);
}
int
setnetgrent (const char *group)
{
@ -135,10 +140,7 @@ setnetgrent (const char *group)
__libc_lock_lock (lock);
/* Free list of all netgroup names from last run. */
free_memory ();
result = internal_setnetgrent (group);
result = __internal_setnetgrent (group, &dataset);
__libc_lock_unlock (lock);
@ -147,14 +149,12 @@ setnetgrent (const char *group)
void
endnetgrent (void)
__internal_endnetgrent (struct __netgrent *datap)
{
service_user *old_nip;
enum nss_status (*fct) (void);
enum nss_status (*fct) (struct __netgrent *);
int no_more;
__libc_lock_lock (lock);
/* Remember which was the last used service. */
old_nip = nip;
@ -163,66 +163,75 @@ endnetgrent (void)
while (! no_more)
{
/* Ignore status, we force check in `__nss_next'. */
(void) (*fct) ();
(void) (*fct) (datap);
no_more = (nip == old_nip
|| __nss_next (&nip, "endnetgrent", (void **) &fct, 0, 1));
}
/* Now free list of all netgroup names from last run. */
free_memory ();
free_memory (datap);
}
void
endnetgrent (void)
{
__libc_lock_lock (lock);
__internal_endnetgrent (&dataset);
__libc_lock_unlock (lock);
}
int
__getnetgrent_r (char **hostp, char **userp, char **domainp,
__internal_getnetgrent (char **hostp, char **userp, char **domainp,
struct __netgrent *datap,
char *buffer, size_t buflen)
{
enum nss_status (*fct) (struct __netgrent *, char *, int);
struct __netgrent result;
int no_more;
/* Initialize status to return if no more functions are found. */
enum nss_status status = NSS_STATUS_NOTFOUND;
__libc_lock_lock (lock);
/* Run through available functions, starting with the same function last
run. We will repeat each function as long as it succeeds, and then go
on to the next service action. */
no_more = setup ((void **) &fct, "getnetgrent_r", 0);
while (! no_more)
{
status = (*fct) (&result, buffer, buflen);
status = (*fct) (datap, buffer, buflen);
if (status == NSS_STATUS_RETURN)
{
/* This was the last one for this group. Look at next group
if available. */
int found = 0;
while (needed_groups != NULL && ! found)
while (datap->needed_groups != NULL && ! found)
{
struct name_list *tmp = needed_groups;
needed_groups = needed_groups->next;
tmp->next = known_groups;
known_groups = tmp;
struct name_list *tmp = datap->needed_groups;
datap->needed_groups = datap->needed_groups->next;
tmp->next = datap->known_groups;
datap->known_groups = tmp;
found = internal_setnetgrent (known_groups->name);
found = __internal_setnetgrent_reuse (datap->known_groups->name,
datap);
}
if (found)
continue;
}
else if (status == NSS_STATUS_SUCCESS && result.type == group_val)
else if (status == NSS_STATUS_SUCCESS && datap->type == group_val)
{
/* The last entry was a name of another netgroup. */
struct name_list *namep;
/* Ignore if we've seen the name before. */
for (namep = known_groups; namep != NULL; namep = namep->next)
if (strcmp (result.val.group, namep->name) == 0)
for (namep = datap->known_groups; namep != NULL;
namep = namep->next)
if (strcmp (datap->val.group, namep->name) == 0)
break;
if (namep != NULL)
/* Really ignore. */
@ -230,7 +239,7 @@ __getnetgrent_r (char **hostp, char **userp, char **domainp,
namep = (struct name_list *) malloc (sizeof (struct name_list));
if (namep == NULL
|| (namep->name = __strdup (result.val.group)) == NULL)
|| (namep->name = __strdup (datap->val.group)) == NULL)
{
/* We are out of memory. */
if (namep != NULL)
@ -239,8 +248,8 @@ __getnetgrent_r (char **hostp, char **userp, char **domainp,
}
else
{
namep->next = needed_groups;
needed_groups = namep;
namep->next = datap->needed_groups;
datap->needed_groups = namep;
/* And get the next entry. */
continue;
}
@ -251,14 +260,29 @@ __getnetgrent_r (char **hostp, char **userp, char **domainp,
if (status == NSS_STATUS_SUCCESS)
{
*hostp = result.val.triple.host;
*userp = result.val.triple.user;
*domainp = result.val.triple.domain;
*hostp = datap->val.triple.host;
*userp = datap->val.triple.user;
*domainp = datap->val.triple.domain;
}
return status == NSS_STATUS_SUCCESS ? 1 : 0;
}
/* The real entry point. */
int
__getnetgrent_r (char **hostp, char **userp, char **domainp,
char *buffer, size_t buflen)
{
enum nss_status status;
__libc_lock_lock (lock);
status = __internal_getnetgrent (hostp, userp, domainp, &dataset,
buffer, buflen);
__libc_lock_unlock (lock);
return status == NSS_STATUS_SUCCESS ? 1 : 0;
return status;
}
weak_alias (__getnetgrent_r, getnetgrent_r)
@ -267,18 +291,16 @@ int
innetgr (const char *netgroup, const char *host, const char *user,
const char *domain)
{
int (*setfct) (const char *);
void (*endfct) (void);
int (*setfct) (const char *, struct __netgrent *);
void (*endfct) (struct __netgrent *);
int (*getfct) (struct __netgrent *, char *, int);
struct name_list *known;
struct name_list *needed;
int result = 0;
int no_more;
struct name_list *known = NULL;
struct name_list *needed = NULL;
const char *current_group = netgroup;
int real_entry = 0;
__libc_lock_lock (lock);
/* Walk through the services until we found an answer or we shall
not work further. We can do some optimization here. Since all
services must provide the `setnetgrent' function we can do all
@ -289,14 +311,17 @@ innetgr (const char *netgroup, const char *host, const char *user,
while (! no_more)
{
enum nss_status status;
struct __netgrent entry;
/* Clear the space for the netgroup data. */
bzero (&entry, sizeof (entry));
/* Open netgroup. */
status = (*setfct) (current_group);
status = (*setfct) (current_group, &entry);
if (status == NSS_STATUS_SUCCESS
&& __nss_lookup (&nip, "getnetgrent_r", (void **) &getfct) == 0)
{
char buffer[1024];
struct __netgrent entry;
while ((*getfct) (&entry, buffer, sizeof buffer)
== NSS_STATUS_SUCCESS)
@ -356,7 +381,7 @@ innetgr (const char *netgroup, const char *host, const char *user,
/* Free all resources of the service. */
if (__nss_lookup (&nip, "endnetgrent", (void **) &endfct) == 0)
(*endfct) ();
(*endfct) (&entry);
/* Look for the next service. */
no_more = __nss_next (&nip, "setnetgrent",
@ -377,8 +402,6 @@ innetgr (const char *netgroup, const char *host, const char *user,
break;
}
__libc_lock_unlock (lock);
/* Free the memory. */
while (known != NULL)
{

View File

@ -20,6 +20,16 @@ Boston, MA 02111-1307, USA. */
#ifndef _NETGROUP_H
#define _NETGROUP_H 1
/* A netgroup can consist of names of other netgroups. We have to
track which netgroups were read and which still have to be read. */
struct name_list
{
const char *name;
struct name_list *next;
};
/* Dataset for iterating netgroups. */
struct __netgrent
{
enum { triple_val, group_val } type;
@ -36,6 +46,25 @@ struct __netgrent
const char *group;
} val;
/* Room for the data kept between the calls to the netgroup
functions. We must avoid global variables. */
char *data;
size_t data_size;
char *cursor;
int first;
struct name_list *known_groups;
struct name_list *needed_groups;
};
/* The internal netgroup handling functions might be called from outside. */
extern int __internal_setnetgrent (const char *group,
struct __netgrent *datap);
extern void __internal_endnetgrent (struct __netgrent *datap);
extern int __internal_getnetgrent_r (char **hostp, char **userp,
char **domainp, struct __netgrent *datap,
char *buffer, size_t buflen);
#endif /* netgroup.h */

View File

@ -124,8 +124,10 @@ it must have been specified to compile as thread safe.
@end defvr
We recommend you use @code{_GNU_SOURCE} in new programs. If you don't
specify the @samp{-ansi} option to GCC and don't define any of these macros
explicitly, the effect is the same as defining @code{_GNU_SOURCE}.
specify the @samp{-ansi} option to GCC and don't define any of these
macros explicitly, the effect is the same as defining
@code{_POSIX_C_SOURCE} to 2 and @code{_POSIX_SOURCE},
@code{_SVID_SOURCE}, and @code{_BSD_SOURCE} to 1.
When you define a feature test macro to request a larger class of features,
it is harmless to define in addition a feature test macro for a subset of

View File

@ -43,6 +43,8 @@ derived work is distributed under the terms of a permission notice
identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that the text of the translation of the section entitled ``GNU
Library General Public License'' must be approved for accuracy by the
Foundation.
@end ifinfo

View File

@ -13,8 +13,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "nsswitch.h"

View File

@ -13,8 +13,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <libc-lock.h>
@ -48,17 +48,17 @@ Boston, MA 02111-1307, USA. */
/* To make the real sources a bit prettier. */
#define REENTRANT_GETNAME APPEND_R (GETFUNC_NAME)
#define APPEND_R(name) APPEND_R1 (name)
#define APPEND_R1(name) name##_r
#define INTERNAL(name) INTERNAL1 (name)
#define INTERNAL1(name) __##name
#define APPEND_R(Name) CONCAT2_2 (Name, _r)
#define INTERNAL(Name) CONCAT2_2 (__, Name)
#define CONCAT2_1(Pre, Post) CONCAT2_2 (Pre, Post)
#define CONCAT2_2(Pre, Post) Pre##Post
#define SETFUNC_NAME_STRING STRINGIZE (SETFUNC_NAME)
#define GETFUNC_NAME_STRING STRINGIZE (REENTRANT_GETNAME)
#define ENDFUNC_NAME_STRING STRINGIZE (ENDFUNC_NAME)
#define DATABASE_NAME_STRING STRINGIZE (DATABASE_NAME)
#define STRINGIZE(name) STRINGIZE1 (name)
#define STRINGIZE1(name) #name
#define STRINGIZE(Name) STRINGIZE1 (Name)
#define STRINGIZE1(Name) #Name
#define DB_LOOKUP_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup)
#define CONCAT3_1(Pre, Name, Post) CONCAT3_2 (Pre, Name, Post)
@ -74,9 +74,13 @@ Boston, MA 02111-1307, USA. */
#endif
/* Some databases take the `stayopen' flag. */
#ifndef STAYOPEN
#ifdef STAYOPEN
# define STAYOPEN_TMP CONCAT2_1 (STAYOPEN, _tmp)
# define STAYOPEN_TMPVAR CONCAT2_1 (STAYOPEN_VAR, _tmp)
#else
# define STAYOPEN void
# define STAYOPEN_VAR
# define STAYOPEN_TMPVAR
#endif
/* Prototype for the setXXXent functions we use here. */
@ -95,6 +99,13 @@ static service_user *nip;
/* Remember the first service_entry, it's always the same. */
static service_user *startp;
#ifdef STAYOPEN_TMP
/* We need to remember the last `stayopen' flag given by the user
since the `setent' function is only called for the first available
service. */
static STAYOPEN_TMP;
#endif
/* Protect above variable against multiple uses at the same time. */
__libc_lock_define_initialized (static, lock)
@ -143,15 +154,21 @@ SETFUNC_NAME (STAYOPEN)
__libc_lock_lock (lock);
/* Cycle through all the services and run their setXXent functions. */
/* Cycle through the services and run their `setXXent' functions until
we find an available service. */
no_more = setup ((void **) &fct, SETFUNC_NAME_STRING, 1);
while (! no_more)
{
/* Ignore status, we force check in __NSS_NEXT. */
(void) (*fct) (STAYOPEN_VAR);
enum nss_status status = (*fct) (STAYOPEN_VAR);
no_more = __nss_next (&nip, SETFUNC_NAME_STRING, (void **) &fct, 0, 1);
no_more = __nss_next (&nip, SETFUNC_NAME_STRING, (void **) &fct,
status, 1);
}
nip = NULL;
#ifdef STAYOPEN_TMP
STAYOPEN_TMPVAR = STAYOPEN_VAR;
#endif
__libc_lock_unlock (lock);
}
@ -182,6 +199,7 @@ ENDFUNC_NAME (void)
no_more = __nss_next (&nip, ENDFUNC_NAME_STRING, (void **) &fct, 0, 1);
}
nip = NULL;
__libc_lock_unlock (lock);
}
@ -214,10 +232,26 @@ INTERNAL (REENTRANT_GETNAME) (LOOKUP_TYPE *resbuf, char *buffer, size_t buflen,
no_more = setup ((void **) &fct, GETFUNC_NAME_STRING, 0);
while (! no_more)
{
service_user *current_nip = nip;
status = (*fct) (resbuf, buffer, buflen H_ERRNO_VAR);
no_more = __nss_next (&nip, GETFUNC_NAME_STRING, (void **) &fct,
status, 0);
if (! no_more && current_nip != nip)
/* Call the `setXXent' function. This wasn't done before. */
do
{
set_function *sfct;
no_more = __nss_lookup (&nip, SETFUNC_NAME_STRING,
(void **) &sfct);
if (! no_more)
status = (*sfct) (STAYOPEN_TMPVAR);
}
while (! no_more && status != NSS_STATUS_SUCCESS);
}
__libc_lock_unlock (lock);

View File

@ -13,9 +13,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include <ctype.h>
@ -54,6 +54,8 @@ __libc_lock_define_initialized (static, lock)
/* Maintenance of the shared stream open on the database file. */
static FILE *stream;
static fpos_t position;
static enum { none, getent, getby } last_use;
static int keep_stream;
/* Open database file if not already opened. */
@ -90,6 +92,15 @@ CONCAT(_nss_files_set,ENTNAME) (int stayopen)
status = internal_setent (stayopen);
if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
{
fclose (stream);
stream = NULL;
status = NSS_STATUS_UNAVAIL;
}
last_use = getent;
__libc_lock_unlock (lock);
return status;
@ -182,12 +193,26 @@ CONCAT(_nss_files_get,ENTNAME_r) (struct STRUCTURE *result,
char *buffer, int buflen H_ERRNO_PROTO)
{
/* Return next entry in host file. */
int status;
int status = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
/* If the last use was not by the getent function we need the
position the stream. */
if (last_use != getent)
if (fsetpos (stream, &position) < 0)
status = NSS_STATUS_UNAVAIL;
else
last_use = getent;
if (status == NSS_STATUS_SUCCESS)
{
status = internal_getent (result, buffer, buflen H_ERRNO_ARG);
/* Remember this position. */
fgetpos (stream, &position);
}
__libc_lock_unlock (lock);
return status;
@ -218,6 +243,9 @@ _nss_files_get##name##_r (proto, \
/* Reset file pointer to beginning or open file. */ \
internal_setent (keep_stream); \
\
/* Tell getent function that we have repositioned the file pointer. */ \
last_use = getby; \
\
while ((status = internal_getent (result, buffer, buflen H_ERRNO_ARG)) \
== NSS_STATUS_SUCCESS) \
{ break_if_match } \

View File

@ -14,13 +14,12 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include <errno.h>
#include <libc-lock.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
@ -31,39 +30,27 @@ Boston, MA 02111-1307, USA. */
#define DATAFILE "/etc/netgroup"
/* Locks the static variables in this file. */
__libc_lock_define_initialized (static, lock)
/* We share a single place where we store the data for the current
netgroup. This buffer is allocated by `setnetgrent' and freed on
the next call of this function or when calling `endnetgrent'. */
static char *data;
static size_t data_size;
static char *cursor;
static int first;
#define EXPAND(needed) \
do \
{ \
size_t old_cursor = cursor - data; \
size_t old_cursor = result->cursor - result->data; \
\
data_size += 512 > 2 * needed ? 512 : 2 * needed; \
data = realloc (data, data_size); \
result->data_size += 512 > 2 * needed ? 512 : 2 * needed; \
result->data = realloc (result->data, result->data_size); \
\
if (data == NULL) \
if (result->data == NULL) \
{ \
status = NSS_STATUS_UNAVAIL; \
goto the_end; \
} \
\
cursor = data + old_cursor; \
result->cursor = result->data + old_cursor; \
} \
while (0)
enum nss_status
_nss_files_setnetgrent (const char *group)
_nss_files_setnetgrent (const char *group, struct __netgrent *result)
{
FILE *fp;
enum nss_status status;
@ -71,8 +58,6 @@ _nss_files_setnetgrent (const char *group)
if (group[0] == '\0')
return NSS_STATUS_UNAVAIL;
__libc_lock_lock (lock);
/* Find the netgroups file and open it. */
fp = fopen (DATAFILE, "r");
if (fp == NULL)
@ -86,7 +71,7 @@ _nss_files_setnetgrent (const char *group)
const ssize_t group_len = strlen (group);
status = NSS_STATUS_NOTFOUND;
cursor = data;
result->cursor = result->data;
while (!feof (fp))
{
@ -108,8 +93,9 @@ _nss_files_setnetgrent (const char *group)
{
/* Store the data from the first line. */
EXPAND (curlen - group_len);
memcpy (cursor, &line[group_len + 1], curlen - group_len);
cursor += (curlen - group_len) - 1;
memcpy (result->cursor, &line[group_len + 1],
curlen - group_len);
result->cursor += (curlen - group_len) - 1;
}
while (line[curlen - 1] == '\n' && line[curlen - 2] == '\\')
@ -117,7 +103,7 @@ _nss_files_setnetgrent (const char *group)
/* Yes, we have a continuation line. */
if (found)
/* Remove these characters from the stored line. */
cursor -= 2;
result->cursor -= 2;
/* Get netxt line. */
curlen = getline (&line, &line_len, fp);
@ -130,11 +116,11 @@ _nss_files_setnetgrent (const char *group)
EXPAND (1 + curlen + 1);
/* Add separator in case next line starts immediately. */
*cursor++ = ' ';
*result->cursor++ = ' ';
/* Copy new line. */
memcpy (cursor, line, curlen + 1);
cursor += curlen;
memcpy (result->cursor, line, curlen + 1);
result->cursor += curlen;
}
}
@ -142,8 +128,8 @@ _nss_files_setnetgrent (const char *group)
{
/* Now we have read the line. */
status = NSS_STATUS_SUCCESS;
cursor = data;
first = 1;
result->cursor = result->data;
result->first = 1;
break;
}
}
@ -154,33 +140,27 @@ _nss_files_setnetgrent (const char *group)
fclose (fp);
}
__libc_lock_unlock (lock);
return status;
}
int
_nss_files_endnetgrent (void)
_nss_files_endnetgrent (struct __netgrent *result)
{
__libc_lock_lock (lock);
/* Free allocated memory for data if some is present. */
if (data != NULL)
if (result->data != NULL)
{
free (data);
data = NULL;
data_size = 0;
cursor = NULL;
free (result->data);
result->data = NULL;
result->data_size = 0;
result->cursor = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
enum nss_status
static enum nss_status
_nss_netgroup_parseline (char **cursor, struct __netgrent *result,
char *buffer, int buflen)
{
@ -216,31 +196,31 @@ _nss_netgroup_parseline (char **cursor, struct __netgrent *result,
if (! last)
++cp;
*cursor = cp;
first = 0;
result->first = 0;
return NSS_STATUS_SUCCESS;
}
return first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
}
/* Match host name. */
host = ++cp;
while (*cp != ',')
if (*cp++ == '\0')
return first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
/* Match user name. */
user = ++cp;
while (*cp != ',')
if (*cp++ == '\0')
return first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
/* Match domain name. */
domain = ++cp;
while (*cp != ')')
if (*cp++ == '\0')
return first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
++cp;
@ -271,7 +251,7 @@ _nss_netgroup_parseline (char **cursor, struct __netgrent *result,
/* Rememember where we stopped reading. */
*cursor = cp;
first = 0;
result->first = 0;
}
return status;
@ -283,11 +263,7 @@ _nss_files_getnetgrent_r (struct __netgrent *result, char *buffer, int buflen)
{
enum nss_status status;
__libc_lock_lock (lock);
status = _nss_netgroup_parseline (&cursor, result, buffer, buflen);
__libc_lock_unlock (lock);
status = _nss_netgroup_parseline (&result->cursor, result, buffer, buflen);
return status;
}

View File

@ -13,9 +13,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include <errno.h>

View File

@ -32,6 +32,7 @@ struct spent_data {};
DB_LOOKUP (spnam, 1 + strlen (name), (".%s", name),
{
if (! strcmp (name, result->sp_namp))
if (name[0] != '+' && name[0] != '-'
&& ! strcmp (name, result->sp_namp))
break;
}, const char *name)

View File

@ -13,8 +13,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <ctype.h>

View File

@ -12,9 +12,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <ctype.h>
#include <stdio.h>
@ -31,6 +31,21 @@ struct pwent_data {};
LINE_PARSER
(,
STRING_FIELD (result->pw_name, ISCOLON, 0);
if (line[0] == '\0'
&& (result->pw_name[0] == '+' || result->pw_name[0] == '-'))
{
/* This a special case. We allow lines containing only a `+' sign
since this is used for nss_compat. All other services will
reject this entry later. Initialize all other fields now. */
result->pw_passwd = NULL;
result->pw_uid = 0;
result->pw_gid = 0;
result->pw_gecos = NULL;
result->pw_dir = NULL;
result->pw_shell = NULL;
}
else
{
STRING_FIELD (result->pw_passwd, ISCOLON, 0);
if (result->pw_name[0] == '+' || result->pw_name[0] == '-')
{
@ -45,6 +60,7 @@ LINE_PARSER
STRING_FIELD (result->pw_gecos, ISCOLON, 0);
STRING_FIELD (result->pw_dir, ISCOLON, 0);
result->pw_shell = line;
}
)

View File

@ -29,14 +29,14 @@ case $1 in
if test -d $2; then
fromname=.
from=`echo $2 | sed 's%/$%%' | sed 's%^/%%'`
from=`echo $2 | sed 's%/$%%'`
else
fromname=`echo $2 | sed 's%.*/\([^/]*\)$%\1%'`
from=`echo $2 | sed "s%/*$fromname$%%" | sed 's%^/%%'`
from=`echo $2 | sed "s%/*$fromname$%%"`
fi
case $from in
/*) ;;
/*) from=`echo $from | sed 's%^/%%'` ;;
?*) from=`cd $from && pwd | sed 's%^/%%'` ;;
*) from=`pwd | sed 's%^/%%'` ;;
esac

View File

@ -36,6 +36,20 @@ struct spent_data {};
LINE_PARSER
(,
STRING_FIELD (result->sp_namp, ISCOLON, 0);
if (line[0] == '\0'
&& (result->sp_namp[0] == '+' || result->sp_namp[0] == '-'))
{
result->sp_pwdp = NULL;
result->sp_lstchg = 0;
result->sp_min = 0;
result->sp_max = 0;
result->sp_warn = -1l;
result->sp_inact = -1l;
result->sp_expire = -1l;
result->sp_flag = ~0ul;
}
else
{
STRING_FIELD (result->sp_pwdp, ISCOLON, 0);
INT_FIELD (result->sp_lstchg, ISCOLON, 0, 10, (long int));
INT_FIELD (result->sp_min, ISCOLON, 0, 10, (long int));
@ -45,9 +59,9 @@ LINE_PARSER
if (*line == '\0')
{
/* The old form. */
result->sp_warn = (long int) -1;
result->sp_inact = (long int) -1;
result->sp_expire = (long int) -1;
result->sp_warn = -1l;
result->sp_inact = -1l;
result->sp_expire = -1l;
result->sp_flag = ~0ul;
}
else
@ -64,6 +78,7 @@ LINE_PARSER
else
result->sp_flag = ~0ul;
}
}
)

View File

@ -100,6 +100,10 @@ extern int __sigpause __P ((int __mask));
extern int sigblock __P ((int __mask));
extern int sigsetmask __P ((int __mask));
extern int sigpause __P ((int __mask));
/* This function is here only for compatibility.
Use `sigprocmask' instead. */
extern int siggetmask __P ((void));
#endif /* Use BSD. */

View File

@ -28,7 +28,7 @@ Cambridge, MA 02139, USA. */
#include <unistd.h>
#include <sys/param.h>
static char cwd[1024];
static char cwd[PATH_MAX];
static size_t cwd_len;
struct {

View File

@ -67,7 +67,14 @@ __fpathconf (fd, name)
case _PC_NAME_MAX:
#ifdef NAME_MAX
return NAME_MAX;
{
struct statfs buf;
if (__fstatfs (fd, &buf) < 0)
return errno == ENOSYS ? NAME_MAX : -1;
else
return buf.f_namelen;
}
#else
__set_errno (ENOSYS);
return -1;
@ -75,14 +82,7 @@ __fpathconf (fd, name)
case _PC_PATH_MAX:
#ifdef PATH_MAX
{
struct statfs buf;
if (__fstatfs (fd, &buf) < 0)
return errno == ENOSYS ? PATH_MAX : -1;
else
return buf.f_namelen;
}
return PATH_MAX;
#else
__set_errno (ENOSYS);
return -1;

View File

@ -38,7 +38,7 @@ unsetenv (name)
__set_errno (ENOSYS);
}
stub_warning (unseenv)
stub_warning (unsetenv)
int

View File

@ -17,6 +17,7 @@ sys/kdaemon.h
sys/klog.h
sys/module.h
sys/mount.h
sys/mtio.h
sys/procfs.h
sys/quota.h
sys/socketcall.h

View File

@ -0,0 +1,32 @@
/* Copyright (C) 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef _SYS_MTIO_H
#define _SYS_MTIO_H 1
/* Get necessary definitions from system and kernel headers. */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/mtio.h>
/* Specifiy default tape device. */
#ifndef DEFTAPE
# define DEFTAPE "/dev/tape"
#endif
#endif /* mtio.h */