File: find_misc.c

package info (click to toggle)
sfind 1.2-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 3,404 kB
  • ctags: 2,727
  • sloc: ansic: 16,006; sh: 3,297; makefile: 106
file content (146 lines) | stat: -rw-r--r-- 3,145 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* @(#)find_misc.c	1.7 06/09/13 Copyright 2004-2005 J. Schilling */
#ifndef lint
static	char sccsid[] =
	"@(#)find_misc.c	1.7 06/09/13 Copyright 2004-2005 J. Schilling";
#endif
/*
 *	Copyright (c) 2004-2005 J. Schilling
 */
/*
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * See the file CDDL.Schily.txt in this distribution for details.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file CDDL.Schily.txt from this distribution.
 */

#include <schily/mconfig.h>
#include <schily/unistd.h>
#include <schily/standard.h>
#include <schily/stat.h>
#include <schily/schily.h>
#include <schily/nlsdefs.h>

#include "find_misc.h"

#ifdef	USE_ACL
#ifdef	HAVE_SYS_ACL_H
#	include <sys/acl.h>
#endif
#ifdef	HAVE_ACL_LIBACL_H
#	include <acl/libacl.h>	/* Needed for acl_extended_file() */
#endif
#endif

/*
 * Define some things that either are missing or defined in a different way
 * on SCO UnixWare
 */
#if	defined(UNIXWARE) && defined(HAVE_ACL)
typedef struct acl	aclent_t;
#endif
#ifndef	GETACL
#define	GETACL	ACL_GET
#endif
#ifndef	SETACL
#define	SETACL	ACL_SET
#endif
#ifndef	GETACLCNT
#define	GETACLCNT	ACL_CNT
#endif
#ifndef	MIN_ACL_ENTRIES
#define	MIN_ACL_ENTRIES	NACLBASE
#endif

EXPORT	BOOL	has_acl		__PR((char *name, char *sname, struct stat *sp));
EXPORT	BOOL	has_xattr	__PR((char *sname));

EXPORT BOOL
has_acl(name, sname, sp)
	char	*name;
	char	*sname;
	struct stat *sp;
{
#ifdef	USE_ACL
#ifdef	HAVE_SUN_ACL	/* Solaris & UnixWare */
	int	aclcount;

	/*
	 * Symlinks don't have ACLs
	 */
	if (S_ISLNK(sp->st_mode))
		return (FALSE);
#ifdef	HAVE_ST_ACLCNT
	return (sp->st_aclcnt > MIN_ACL_ENTRIES);
#else
	if ((aclcount = acl(sname, GETACLCNT, 0, NULL)) < 0) {
		errmsg(gettext("Cannot get ACL count for '%s'.\n"), name);
		return (FALSE);
	}
	return (aclcount > MIN_ACL_ENTRIES);
#endif	/* HAVE_ST_ACLCNT */
#else	/* HAVE_SUN_ACL */
	/*
	 * Non Sun ACL implementations.
	 */
#ifdef	HAVE_ACL_EXTENDED_FILE
	/*
	 * Linux extension
	 */
	return (acl_extended_file(sname) == 1);
#else
#ifdef	HAVE_POSIX_ACL
	acl_t	acl;

	if ((acl = acl_get_file(sname, ACL_TYPE_ACCESS)) != NULL) {
		int	id = ACL_FIRST_ENTRY;
		int	num;
		acl_entry_t dummy;

		for (num = 0; acl_get_entry(acl, id, &dummy); num++)
			id = ACL_NEXT_ENTRY;
		acl_free(acl);
		if (num > 3)
			return (TRUE);
	}
	/*
	 * Only directories have DEFAULT ACLs
	 */
	if (!S_ISDIR(sp->st_mode))
		return (FALSE);
	if ((acl = acl_get_file(sname, ACL_TYPE_DEFAULT)) != NULL) {
		int	id = ACL_FIRST_ENTRY;
		int	num;
		acl_entry_t dummy;

		for (num = 0; acl_get_entry(acl, id, &dummy); num++)
			id = ACL_NEXT_ENTRY;
		acl_free(acl);
		if (num > 0)
			return (TRUE);
	}
#endif	/* HAVE_POSIX_ACL */

	return (FALSE);

#endif
#endif	/* HAVE_SUN_ACL */
#else	/* USE_ACL */
	return (FALSE);
#endif	/* USE_ACL */
}

EXPORT BOOL
has_xattr(sname)
	char	*sname;
{
#ifdef	_PC_XATTR_EXISTS
		return (pathconf(sname, _PC_XATTR_EXISTS) > 0);
#else
		return (FALSE);
#endif
}