diff -Naur --exclude=debian glibc-pre2.1-2.0.106.orig/sysdeps/unix/sysv/linux/alpha/chown.c glibc-pre2.1-2.0.106/sysdeps/unix/sysv/linux/alpha/chown.c --- glibc-pre2.1-2.0.106.orig/sysdeps/unix/sysv/linux/alpha/chown.c Thu Jan 1 00:00:00 1970 +++ glibc-pre2.1-2.0.106/sysdeps/unix/sysv/linux/alpha/chown.c Mon Aug 24 17:58:59 1998 @@ -0,0 +1,131 @@ +/* chown() compatibility. + Copyright (C) 1998 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. */ + +#include +#include +#include +#include +#include +#include + +/* + In Linux 2.1.x the chown functions have been changed. A new function lchown + was introduced. The new chown now follows symlinks - the old chown and the + new lchown do not follow symlinks. + This file emulates chown() under the old kernels. +*/ + +extern int __syscall_chown (const char *__file, + uid_t __owner, gid_t __group); + +int +__chown (const char *file, uid_t owner, gid_t group) +{ + int err; + int old_errno; + char link[PATH_MAX+2]; + char path[2*PATH_MAX+4]; + int loopct; + int filelen; + static int libc_old_chown = 0 /* -1=old linux, 1=new linux, 0=unknown */; + + if (libc_old_chown == 1) + return __syscall_chown (file, owner, group); + + old_errno = errno; + +#ifdef __NR_lchown + if (libc_old_chown == 0) + { + err = __syscall_chown (file, owner, group); + if (err != -1 || errno != ENOSYS) + { + libc_old_chown = 1; + return err; + } + libc_old_chown = -1; + } +#endif + + err = __readlink (file, link, PATH_MAX+1); + if (err == -1) + { + errno = old_errno; + return __lchown(file, owner, group); + } + + filelen = strlen (file) + 1; + if (filelen > sizeof(path)) + { + errno = ENAMETOOLONG; + return -1; + } + memcpy (path, file, filelen); + + /* 'The system has an arbitrary limit...' In practise, we'll hit + ENAMETOOLONG before this, usually. */ + for (loopct = 0; loopct < 128; loopct++) + { + int linklen; + + if (err >= PATH_MAX+1) + { + errno = ENAMETOOLONG; + return -1; + } + + link[err] = 0; /* Null-terminate string, just-in-case. */ + + linklen = strlen (link) + 1; + + if (link[0] == '/') + memcpy (path, link, linklen); + else + { + filelen = strlen (path); + + while (filelen > 1 && path[filelen-1] == '/') + filelen--; + while (filelen > 0 && path[filelen-1] != '/') + filelen--; + if (filelen + linklen > sizeof(path)) + { + errno = ENAMETOOLONG; + return -1; + } + memcpy (path+filelen, link, linklen); + } + + err = __readlink(path, link, PATH_MAX+1); + + if (err == -1) + { + errno = old_errno; + return __lchown(path, owner, group); + } + } + errno = ELOOP; + return -1; +} + +#if defined PIC && defined DO_VERSIONING +default_symbol_version (__chown, chown, GLIBC_2.1); +#else +weak_alias (__chown, chown) +#endif diff -Naur --exclude=debian glibc-pre2.1-2.0.106.orig/sysdeps/unix/sysv/linux/alpha/lchown.S glibc-pre2.1-2.0.106/sysdeps/unix/sysv/linux/alpha/lchown.S --- glibc-pre2.1-2.0.106.orig/sysdeps/unix/sysv/linux/alpha/lchown.S Thu Jan 1 00:00:00 1970 +++ glibc-pre2.1-2.0.106/sysdeps/unix/sysv/linux/alpha/lchown.S Mon Aug 24 17:58:59 1998 @@ -0,0 +1,35 @@ +/* lchown system call. + Copyright (C) 1998 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. */ + +/* Some old kernel headers call lchown() 'chown'. The number is + the same. */ + +#include + +#ifdef __NR_lchown + PSEUDO (__lchown, lchown, 3) +#else + PSEUDO (__lchown, chown, 3) +#endif + ret + PSEUDO_END(__lchown) + weak_alias (__lchown, lchown) +#if defined PIC && defined DO_VERSIONING + symbol_version (__lchown, chown, GLIBC_2.0); +#endif diff -Naur --exclude=debian glibc-pre2.1-2.0.106.orig/sysdeps/unix/sysv/linux/alpha/syscalls.list glibc-pre2.1-2.0.106/sysdeps/unix/sysv/linux/alpha/syscalls.list --- glibc-pre2.1-2.0.106.orig/sysdeps/unix/sysv/linux/alpha/syscalls.list Sun Nov 1 07:36:15 1998 +++ glibc-pre2.1-2.0.106/sysdeps/unix/sysv/linux/alpha/syscalls.list Sat Dec 12 02:21:19 1998 @@ -35,6 +35,8 @@ sys_ustat ustat ustat 2 __syscall_ustat sys_mknod xmknod mknod 3 __syscall_mknod +s_chown chown chown 3 __syscall_chown + # proper socket implementations: accept - accept 3 __libc_accept __accept accept bind - bind 3 __bind bind