1/* Provide a stub lchown function for systems that lack it.
2
3   Copyright (C) 1998, 1999, 2002, 2004, 2006, 2007 Free Software
4   Foundation, Inc.
5
6   This program is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3 of the License, or
9   (at your option) any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19/* written by Jim Meyering */
20
21#include <config.h>
22
23/* If the system chown does not follow symlinks, we don't want it
24   replaced by gnulib's chown, which does follow symlinks.  */
25#if CHOWN_MODIFIES_SYMLINK
26# define REPLACE_CHOWN 0
27#endif
28#include <unistd.h>
29
30#include <errno.h>
31#include <sys/stat.h>
32
33/* Some systems don't have EOPNOTSUPP.  */
34#ifndef EOPNOTSUPP
35# ifdef ENOTSUP
36#  define EOPNOTSUPP ENOTSUP
37# else
38/* Some systems don't have ENOTSUP either.  */
39#  define EOPNOTSUPP EINVAL
40# endif
41#endif
42
43/* Work just like chown, except when FILE is a symbolic link.
44   In that case, set errno to EOPNOTSUPP and return -1.
45   But if autoconf tests determined that chown modifies
46   symlinks, then just call chown.  */
47
48int
49lchown (const char *file, uid_t uid, gid_t gid)
50{
51#if ! CHOWN_MODIFIES_SYMLINK
52  struct stat stats;
53
54  if (lstat (file, &stats) == 0 && S_ISLNK (stats.st_mode))
55    {
56      errno = EOPNOTSUPP;
57      return -1;
58    }
59#endif
60
61  return chown (file, uid, gid);
62}
63