[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Cvs-cvs] ccvs/lib ChangeLog Makefile.am Makefile.gnulib ...
From: |
Derek Robert Price |
Subject: |
[Cvs-cvs] ccvs/lib ChangeLog Makefile.am Makefile.gnulib ... |
Date: |
Fri, 24 Aug 2007 18:06:25 +0000 |
CVSROOT: /cvsroot/cvs
Module name: ccvs
Changes by: Derek Robert Price <dprice> 07/08/24 18:06:25
Modified files:
lib : ChangeLog Makefile.am Makefile.gnulib
Makefile.in
Added files:
lib : dirchownmod.c dirchownmod.h lchmod.h
mkancesdirs.c mkancesdirs.h mkdir-p.c mkdir-p.h
quote.c quote.h raise.c savewd.c savewd.h
Log message:
* Makefile.am: Import automated changes from...
* Makefile.gnulib: ...here.
* dirchownmod.c, lchmod.h, mkancesdirs.c, mkancesdirs.h, mkdir-p.c,
mkdir-p.h, quote.c, quote.h, raise.c, savewd.c, savewd.h: New files
from GNULIB.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/ChangeLog?cvsroot=cvs&r1=1.552&r2=1.553
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/Makefile.am?cvsroot=cvs&r1=1.126&r2=1.127
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/Makefile.gnulib?cvsroot=cvs&r1=1.89&r2=1.90
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/Makefile.in?cvsroot=cvs&r1=1.229&r2=1.230
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/dirchownmod.c?cvsroot=cvs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/dirchownmod.h?cvsroot=cvs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/lchmod.h?cvsroot=cvs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/mkancesdirs.c?cvsroot=cvs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/mkancesdirs.h?cvsroot=cvs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/mkdir-p.c?cvsroot=cvs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/mkdir-p.h?cvsroot=cvs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/quote.c?cvsroot=cvs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/quote.h?cvsroot=cvs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/raise.c?cvsroot=cvs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/savewd.c?cvsroot=cvs&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/ccvs/lib/savewd.h?cvsroot=cvs&rev=1.1
Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/cvs/ccvs/lib/ChangeLog,v
retrieving revision 1.552
retrieving revision 1.553
diff -u -b -r1.552 -r1.553
--- ChangeLog 23 Aug 2007 21:35:21 -0000 1.552
+++ ChangeLog 24 Aug 2007 18:06:23 -0000 1.553
@@ -1,3 +1,11 @@
+2007-08-24 Derek Price <address@hidden>
+
+ * Makefile.am: Import automated changes from...
+ * Makefile.gnulib: ...here.
+ * dirchownmod.c, lchmod.h, mkancesdirs.c, mkancesdirs.h, mkdir-p.c,
+ mkdir-p.h, quote.c, quote.h, raise.c, savewd.c, savewd.h: New files
+ from GNULIB.
+
2007-08-23 Derek Price <address@hidden>
* Makefile.am: Import automated changes from...
Index: Makefile.am
===================================================================
RCS file: /cvsroot/cvs/ccvs/lib/Makefile.am,v
retrieving revision 1.126
retrieving revision 1.127
diff -u -b -r1.126 -r1.127
--- Makefile.am 23 Aug 2007 21:35:22 -0000 1.126
+++ Makefile.am 24 Aug 2007 18:06:23 -0000 1.127
@@ -717,6 +717,13 @@
## end gnulib module inttypes
+## begin gnulib module lchmod
+
+
+EXTRA_DIST += lchmod.h
+
+## end gnulib module lchmod
+
## begin gnulib module lchown
@@ -895,6 +902,15 @@
## end gnulib module minmax
+## begin gnulib module mkancesdirs
+
+
+EXTRA_DIST += mkancesdirs.c mkancesdirs.h
+
+EXTRA_libcvs_a_SOURCES += mkancesdirs.c
+
+## end gnulib module mkancesdirs
+
## begin gnulib module mkdir
@@ -904,6 +920,15 @@
## end gnulib module mkdir
+## begin gnulib module mkdir-p
+
+
+EXTRA_DIST += dirchownmod.c dirchownmod.h mkdir-p.c mkdir-p.h
+
+EXTRA_libcvs_a_SOURCES += dirchownmod.c mkdir-p.c
+
+## end gnulib module mkdir-p
+
## begin gnulib module mkstemp
@@ -984,6 +1009,15 @@
## end gnulib module pathmax
+## begin gnulib module quote
+
+
+EXTRA_DIST += quote.c quote.h
+
+EXTRA_libcvs_a_SOURCES += quote.c
+
+## end gnulib module quote
+
## begin gnulib module quotearg
@@ -993,6 +1027,15 @@
## end gnulib module quotearg
+## begin gnulib module raise
+
+
+EXTRA_DIST += raise.c
+
+EXTRA_libcvs_a_SOURCES += raise.c
+
+## end gnulib module raise
+
## begin gnulib module readlink
@@ -1054,6 +1097,12 @@
## end gnulib module save-cwd
+## begin gnulib module savewd
+
+libcvs_a_SOURCES += savewd.h savewd.c
+
+## end gnulib module savewd
+
## begin gnulib module setenv
Index: Makefile.gnulib
===================================================================
RCS file: /cvsroot/cvs/ccvs/lib/Makefile.gnulib,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -b -r1.89 -r1.90
--- Makefile.gnulib 23 Aug 2007 21:35:22 -0000 1.89
+++ Makefile.gnulib 24 Aug 2007 18:06:23 -0000 1.90
@@ -9,7 +9,7 @@
# the same distribution terms as the rest of that program.
#
# Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --dir=. --lib=libcvs --source-base=lib
--m4-base=m4 --doc-base=doc --aux-dir=build-aux --no-libtool --macro-prefix=gl
atexit base64 canon-host canonicalize closeout crypto/md5 dirname dup2 error
exit exitfail extensions fnmatch fnmatch-posix fseeko ftello ftruncate getdate
gethostname getline getlogin_r getndelim2 getnline getopt getpagesize
getpass-gnu gettext gettime gettimeofday glob inttypes lstat malloc mbsstr
memmove minmax mkdir mkstemp mktime mreadlink-with-size nanosleep pathmax
quotearg readlink realloc regex rename save-cwd setenv stat-macros stdbool
stdint strcase strdup strerror strftime strtoul strtoumax time_r timespec tzset
unlocked-io vasnprintf vasprintf xalloc-die xgethostname xsize yesno
+# Reproduce by: gnulib-tool --import --dir=. --lib=libcvs --source-base=lib
--m4-base=m4 --doc-base=doc --aux-dir=build-aux --no-libtool --macro-prefix=gl
atexit base64 canon-host canonicalize closeout crypto/md5 dirname dup2 error
exit exitfail extensions fnmatch fnmatch-posix fseeko ftello ftruncate getdate
gethostname getline getlogin_r getndelim2 getnline getopt getpagesize
getpass-gnu gettext gettime gettimeofday glob inttypes lstat malloc mbsstr
memmove minmax mkdir mkdir-p mkstemp mktime mreadlink-with-size nanosleep
pathmax quotearg readlink realloc regex rename save-cwd setenv stat-macros
stdbool stdint strcase strdup strerror strftime strtoul strtoumax time_r
timespec tzset unlocked-io vasnprintf vasprintf xalloc-die xgethostname xsize
yesno
AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects
@@ -661,6 +661,13 @@
## end gnulib module inttypes
+## begin gnulib module lchmod
+
+
+EXTRA_DIST += lchmod.h
+
+## end gnulib module lchmod
+
## begin gnulib module lchown
@@ -839,6 +846,15 @@
## end gnulib module minmax
+## begin gnulib module mkancesdirs
+
+
+EXTRA_DIST += mkancesdirs.c mkancesdirs.h
+
+EXTRA_libcvs_a_SOURCES += mkancesdirs.c
+
+## end gnulib module mkancesdirs
+
## begin gnulib module mkdir
@@ -848,6 +864,15 @@
## end gnulib module mkdir
+## begin gnulib module mkdir-p
+
+
+EXTRA_DIST += dirchownmod.c dirchownmod.h mkdir-p.c mkdir-p.h
+
+EXTRA_libcvs_a_SOURCES += dirchownmod.c mkdir-p.c
+
+## end gnulib module mkdir-p
+
## begin gnulib module mkstemp
@@ -928,6 +953,15 @@
## end gnulib module pathmax
+## begin gnulib module quote
+
+
+EXTRA_DIST += quote.c quote.h
+
+EXTRA_libcvs_a_SOURCES += quote.c
+
+## end gnulib module quote
+
## begin gnulib module quotearg
@@ -937,6 +971,15 @@
## end gnulib module quotearg
+## begin gnulib module raise
+
+
+EXTRA_DIST += raise.c
+
+EXTRA_libcvs_a_SOURCES += raise.c
+
+## end gnulib module raise
+
## begin gnulib module readlink
@@ -998,6 +1041,12 @@
## end gnulib module save-cwd
+## begin gnulib module savewd
+
+libcvs_a_SOURCES += savewd.h savewd.c
+
+## end gnulib module savewd
+
## begin gnulib module setenv
Index: Makefile.in
===================================================================
RCS file: /cvsroot/cvs/ccvs/lib/Makefile.in,v
retrieving revision 1.229
retrieving revision 1.230
diff -u -b -r1.229 -r1.230
--- Makefile.in 23 Aug 2007 21:35:22 -0000 1.229
+++ Makefile.in 24 Aug 2007 18:06:23 -0000 1.230
@@ -97,8 +97,9 @@
$(top_srcdir)/m4/inline.m4 $(top_srcdir)/m4/intlmacosx.m4 \
$(top_srcdir)/m4/intmax_t.m4 $(top_srcdir)/m4/inttypes-pri.m4 \
$(top_srcdir)/m4/inttypes.m4 $(top_srcdir)/m4/inttypes_h.m4 \
- $(top_srcdir)/m4/lchown.m4 $(top_srcdir)/m4/lib-ld.m4 \
- $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/lchmod.m4 $(top_srcdir)/m4/lchown.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 \
$(top_srcdir)/m4/localcharset.m4 $(top_srcdir)/m4/longlong.m4 \
$(top_srcdir)/m4/lseek.m4 $(top_srcdir)/m4/lstat.m4 \
$(top_srcdir)/m4/malloca.m4 $(top_srcdir)/m4/mbchar.m4 \
@@ -107,15 +108,17 @@
$(top_srcdir)/m4/mbstate_t.m4 $(top_srcdir)/m4/md5.m4 \
$(top_srcdir)/m4/memchr.m4 $(top_srcdir)/m4/memmove.m4 \
$(top_srcdir)/m4/mempcpy.m4 $(top_srcdir)/m4/memrchr.m4 \
- $(top_srcdir)/m4/minmax.m4 $(top_srcdir)/m4/mkdir-slash.m4 \
+ $(top_srcdir)/m4/minmax.m4 $(top_srcdir)/m4/mkancesdirs.m4 \
+ $(top_srcdir)/m4/mkdir-p.m4 $(top_srcdir)/m4/mkdir-slash.m4 \
$(top_srcdir)/m4/mkstemp.m4 $(top_srcdir)/m4/mktime.m4 \
$(top_srcdir)/m4/nanosleep.m4 $(top_srcdir)/m4/netinet_in_h.m4 \
$(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/openat.m4 \
$(top_srcdir)/m4/pathmax.m4 $(top_srcdir)/m4/po.m4 \
- $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/quotearg.m4 \
- $(top_srcdir)/m4/readlink.m4 $(top_srcdir)/m4/regex.m4 \
- $(top_srcdir)/m4/rename.m4 $(top_srcdir)/m4/rpmatch.m4 \
- $(top_srcdir)/m4/save-cwd.m4 $(top_srcdir)/m4/setenv.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/quote.m4 \
+ $(top_srcdir)/m4/quotearg.m4 $(top_srcdir)/m4/readlink.m4 \
+ $(top_srcdir)/m4/regex.m4 $(top_srcdir)/m4/rename.m4 \
+ $(top_srcdir)/m4/rpmatch.m4 $(top_srcdir)/m4/save-cwd.m4 \
+ $(top_srcdir)/m4/savewd.m4 $(top_srcdir)/m4/setenv.m4 \
$(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/snprintf.m4 \
$(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sockpfaf.m4 \
$(top_srcdir)/m4/ssize_t.m4 $(top_srcdir)/m4/stdbool.m4 \
@@ -158,7 +161,7 @@
getdate.$(OBJEXT) getnline.$(OBJEXT) localcharset.$(OBJEXT) \
malloca.$(OBJEXT) mbchar.$(OBJEXT) mbslen.$(OBJEXT) \
mbsstr.$(OBJEXT) mreadlink-with-size.$(OBJEXT) \
- openat-die.$(OBJEXT) strnlen1.$(OBJEXT) \
+ openat-die.$(OBJEXT) savewd.$(OBJEXT) strnlen1.$(OBJEXT) \
uniwidth/width.$(OBJEXT) xalloc-die.$(OBJEXT) \
xgethostname.$(OBJEXT) xstrndup.$(OBJEXT)
libcvs_a_OBJECTS = $(am_libcvs_a_OBJECTS)
@@ -529,9 +532,9 @@
base64.h base64.c getdate.y getnline.h getnline.c gettext.h \
localcharset.h localcharset.c malloca.c mbchar.c mbslen.c \
mbsstr.c mbuiter.h minmax.h mreadlink-with-size.c openat-die.c \
- size_max.h strnlen1.h strnlen1.c uniwidth/width.c verify.h \
- xalloc-die.c xgethostname.h xgethostname.c xsize.h xstrndup.h \
- xstrndup.c
+ savewd.h savewd.c size_max.h strnlen1.h strnlen1.c \
+ uniwidth/width.c verify.h xalloc-die.c xgethostname.h \
+ xgethostname.c xsize.h xstrndup.h xstrndup.c
libcvs_a_LIBADD = @LIBOBJS@ $(gl_LIBOBJS) @ALLOCA@
libcvs_a_DEPENDENCIES = $(gl_LIBOBJS) @ALLOCA@
BUILT_SOURCES = $(ALLOCA_H) $(ARPA_INET_H) configmake.h $(DIRENT_H) \
@@ -585,26 +588,27 @@
$(top_srcdir)/build-aux/config.rpath gettime.c gettimeofday.c \
glob-libc.h glob.c glob_.h \
$(top_srcdir)/build-aux/config.rpath inet_ntop.c inet_ntop.h \
- intprops.h inttypes_.h lchown.c \
+ intprops.h inttypes_.h lchmod.h lchown.c \
$(top_srcdir)/build-aux/link-warning.h config.charset \
ref-add.sin ref-del.sin lseek.c lstat.c lstat.h malloc.c \
malloca.h malloca.valgrind mbchar.h memchr.c memmove.c \
- mempcpy.c memrchr.c mkdir.c mkstemp.c mktime.c mreadlink.h \
- nanosleep.c netinet_in_.h at-func.c fchmodat.c fchownat.c \
- fstatat.c mkdirat.c openat-priv.h openat-proc.c openat.c \
- openat.h pathmax.h quotearg.c quotearg.h readlink.c realloc.c \
- regcomp.c regex.c regex.h regex_internal.c regex_internal.h \
- regexec.c rename.c rpmatch.c same-inode.h save-cwd.c \
- save-cwd.h setenv.c setenv.h unsetenv.c snprintf.c \
- stat-macros.h stdbool_.h stdint_.h stdio_.h stdlib_.h \
- strcasecmp.c strncasecmp.c strdup.c streq.h strerror.c \
- strftime.c strftime.h string_.h strndup.c strnlen.c \
- strtoimax.c strtol.c strtoll.c strtoul.c strtoull.c \
- strtoumax.c sys_socket_.h sys_stat_.h sys_time_.h tempname.c \
- tempname.h time_.h time_r.c timespec.h unistd_.h dup-safer.c \
- fd-safer.c pipe-safer.c unistd--.h unistd-safer.h unitypes.h \
- localcharset.h uniwidth.h uniwidth/cjk.h unlocked-io.h \
- asnprintf.c float+.h printf-args.c printf-args.h \
+ mempcpy.c memrchr.c mkancesdirs.c mkancesdirs.h mkdir.c \
+ dirchownmod.c dirchownmod.h mkdir-p.c mkdir-p.h mkstemp.c \
+ mktime.c mreadlink.h nanosleep.c netinet_in_.h at-func.c \
+ fchmodat.c fchownat.c fstatat.c mkdirat.c openat-priv.h \
+ openat-proc.c openat.c openat.h pathmax.h quote.c quote.h \
+ quotearg.c quotearg.h raise.c readlink.c realloc.c regcomp.c \
+ regex.c regex.h regex_internal.c regex_internal.h regexec.c \
+ rename.c rpmatch.c same-inode.h save-cwd.c save-cwd.h setenv.c \
+ setenv.h unsetenv.c snprintf.c stat-macros.h stdbool_.h \
+ stdint_.h stdio_.h stdlib_.h strcasecmp.c strncasecmp.c \
+ strdup.c streq.h strerror.c strftime.c strftime.h string_.h \
+ strndup.c strnlen.c strtoimax.c strtol.c strtoll.c strtoul.c \
+ strtoull.c strtoumax.c sys_socket_.h sys_stat_.h sys_time_.h \
+ tempname.c tempname.h time_.h time_r.c timespec.h unistd_.h \
+ dup-safer.c fd-safer.c pipe-safer.c unistd--.h unistd-safer.h \
+ unitypes.h localcharset.h uniwidth.h uniwidth/cjk.h \
+ unlocked-io.h asnprintf.c float+.h printf-args.c printf-args.h \
printf-parse.c printf-parse.h vasnprintf.c vasnprintf.h \
asprintf.c vasprintf.c wchar_.h wctype_.h wcwidth.c xalloc.h \
xmalloc.c xgetcwd.c xgetcwd.h yesno.c yesno.h
@@ -618,9 +622,10 @@
getline.c getlogin_r.c getndelim2.c getopt.c getopt1.c \
getpass.c gettime.c gettimeofday.c glob.c inet_ntop.c lchown.c \
lseek.c lstat.c malloc.c memchr.c memmove.c mempcpy.c \
- memrchr.c mkdir.c mkstemp.c mktime.c nanosleep.c at-func.c \
- fchmodat.c fchownat.c fstatat.c mkdirat.c openat-proc.c \
- openat.c quotearg.c readlink.c realloc.c regcomp.c regex.c \
+ memrchr.c mkancesdirs.c mkdir.c dirchownmod.c mkdir-p.c \
+ mkstemp.c mktime.c nanosleep.c at-func.c fchmodat.c fchownat.c \
+ fstatat.c mkdirat.c openat-proc.c openat.c quote.c quotearg.c \
+ raise.c readlink.c realloc.c regcomp.c regex.c \
regex_internal.c regexec.c rename.c rpmatch.c save-cwd.c \
setenv.c unsetenv.c snprintf.c strcasecmp.c strncasecmp.c \
strdup.c strerror.c strftime.c strndup.c strnlen.c strtoimax.c \
@@ -727,6 +732,7 @@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@@ -778,6 +784,8 @@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@@ -791,7 +799,9 @@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@@ -801,6 +811,7 @@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
Index: dirchownmod.c
===================================================================
RCS file: dirchownmod.c
diff -N dirchownmod.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dirchownmod.c 24 Aug 2007 18:06:24 -0000 1.1
@@ -0,0 +1,143 @@
+/* Change the ownership and mode bits of a directory.
+
+ Copyright (C) 2006, 2007 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 program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Paul Eggert. */
+
+#include <config.h>
+
+#include "dirchownmod.h"
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "lchmod.h"
+#include "stat-macros.h"
+
+#ifndef HAVE_FCHMOD
+# define HAVE_FCHMOD 0
+# undef fchmod
+# define fchmod(fd, mode) (-1)
+#endif
+
+/* Change the ownership and mode bits of a directory. If FD is
+ nonnegative, it should be a file descriptor associated with the
+ directory; close it before returning. DIR is the name of the
+ directory.
+
+ If MKDIR_MODE is not (mode_t) -1, mkdir (DIR, MKDIR_MODE) has just
+ been executed successfully with umask zero, so DIR should be a
+ directory (not a symbolic link).
+
+ First, set the file's owner to OWNER and group to GROUP, but leave
+ the owner alone if OWNER is (uid_t) -1, and similarly for GROUP.
+
+ Then, set the file's mode bits to MODE, except preserve any of the
+ bits that correspond to zero bits in MODE_BITS. In other words,
+ MODE_BITS is a mask that specifies which of the file's mode bits
+ should be set or cleared. MODE should be a subset of MODE_BITS,
+ which in turn should be a subset of CHMOD_MODE_BITS.
+
+ This implementation assumes the current umask is zero.
+
+ Return 0 if successful, -1 (setting errno) otherwise. Unsuccessful
+ calls may do the chown but not the chmod. */
+
+int
+dirchownmod (int fd, char const *dir, mode_t mkdir_mode,
+ uid_t owner, gid_t group,
+ mode_t mode, mode_t mode_bits)
+{
+ struct stat st;
+ int result = (fd < 0 ? stat (dir, &st) : fstat (fd, &st));
+
+ if (result == 0)
+ {
+ mode_t dir_mode = st.st_mode;
+
+ /* Check whether DIR is a directory. If FD is nonnegative, this
+ check avoids changing the ownership and mode bits of the
+ wrong file in many cases. This doesn't fix all the race
+ conditions, but it is better than nothing. */
+ if (! S_ISDIR (dir_mode))
+ {
+ errno = ENOTDIR;
+ result = -1;
+ }
+ else
+ {
+ /* If at least one of the S_IXUGO bits are set, chown might
+ clear the S_ISUID and S_SGID bits. Keep track of any
+ file mode bits whose values are indeterminate due to this
+ issue. */
+ mode_t indeterminate = 0;
+
+ /* On some systems, chown clears S_ISUID and S_ISGID, so do
+ chown before chmod. On older System V hosts, ordinary
+ users can give their files away via chown; don't worry
+ about that here, since users shouldn't do that. */
+
+ if ((owner != (uid_t) -1 && owner != st.st_uid)
+ || (group != (gid_t) -1 && group != st.st_gid))
+ {
+ result = (0 <= fd
+ ? fchown (fd, owner, group)
+ : mkdir_mode != (mode_t) -1
+ ? lchown (dir, owner, group)
+ : chown (dir, owner, group));
+
+ /* Either the user cares about an indeterminate bit and
+ it'll be set properly by chmod below, or the user
+ doesn't care and it's OK to use the bit's pre-chown
+ value. So there's no need to re-stat DIR here. */
+
+ if (result == 0 && (dir_mode & S_IXUGO))
+ indeterminate = dir_mode & (S_ISUID | S_ISGID);
+ }
+
+ /* If the file mode bits might not be right, use chmod to
+ change them. Don't change bits the user doesn't care
+ about. */
+ if (result == 0 && (((dir_mode ^ mode) | indeterminate) & mode_bits))
+ {
+ mode_t chmod_mode =
+ mode | (dir_mode & CHMOD_MODE_BITS & ~mode_bits);
+ result = (HAVE_FCHMOD && 0 <= fd
+ ? fchmod (fd, chmod_mode)
+ : mkdir_mode != (mode_t) -1
+ ? lchmod (dir, chmod_mode)
+ : chmod (dir, chmod_mode));
+ }
+ }
+ }
+
+ if (0 <= fd)
+ {
+ if (result == 0)
+ result = close (fd);
+ else
+ {
+ int e = errno;
+ close (fd);
+ errno = e;
+ }
+ }
+
+ return result;
+}
Index: dirchownmod.h
===================================================================
RCS file: dirchownmod.h
diff -N dirchownmod.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dirchownmod.h 24 Aug 2007 18:06:24 -0000 1.1
@@ -0,0 +1,2 @@
+#include <sys/types.h>
+int dirchownmod (int, char const *, mode_t, uid_t, gid_t, mode_t, mode_t);
Index: lchmod.h
===================================================================
RCS file: lchmod.h
diff -N lchmod.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lchmod.h 24 Aug 2007 18:06:24 -0000 1.1
@@ -0,0 +1,35 @@
+/* Provide a replacement for lchmod on hosts that lack it.
+
+ Copyright (C) 2005 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 program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Paul Eggert. */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifndef HAVE_LCHMOD
+
+/* The lchmod replacement follows symbolic links. Callers should take
+ this into account; lchmod should be applied only to arguments that
+ are known to not be symbolic links. On hosts that lack lchmod,
+ this can lead to race conditions between the check and the
+ invocation of lchmod, but we know of no workarounds that are
+ reliable in general. You might try requesting support for lchmod
+ from your operating system supplier. */
+
+# define lchmod chmod
+#endif
Index: mkancesdirs.c
===================================================================
RCS file: mkancesdirs.c
diff -N mkancesdirs.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mkancesdirs.c 24 Aug 2007 18:06:24 -0000 1.1
@@ -0,0 +1,154 @@
+/* Make a file's ancestor directories.
+
+ Copyright (C) 2006 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 program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Paul Eggert. */
+
+#include <config.h>
+
+#include "mkancesdirs.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <errno.h>
+#include <unistd.h>
+
+#include "dirname.h"
+#include "savewd.h"
+
+/* Ensure that the ancestor directories of FILE exist, using an
+ algorithm that should work even if two processes execute this
+ function in parallel. Modify FILE as necessary to access the
+ ancestor directories, but restore FILE to an equivalent value
+ if successful.
+
+ WD points to the working directory, using the conventions of
+ savewd.
+
+ Create any ancestor directories that don't already exist, by
+ invoking MAKE_DIR (FILE, COMPONENT, MAKE_DIR_ARG). This function
+ should return 0 if successful and the resulting directory is
+ readable, 1 if successful but the resulting directory might not be
+ readable, -1 (setting errno) otherwise. If COMPONENT is relative,
+ it is relative to the temporary working directory, which may differ
+ from *WD.
+
+ Ordinarily MAKE_DIR is executed with the working directory changed
+ to reflect the already-made prefix, and mkancesdirs returns with
+ the working directory changed a prefix of FILE. However, if the
+ initial working directory cannot be saved in a file descriptor,
+ MAKE_DIR is invoked in a subprocess and this function returns in
+ both the parent and child process, so the caller should not assume
+ any changed state survives other than the EXITMAX component of WD,
+ and the caller should take care that the parent does not attempt to
+ do the work that the child is doing.
+
+ If successful and if this process can go ahead and create FILE,
+ return the length of the prefix of FILE that has already been made.
+ If successful so far but a child process is doing the actual work,
+ return -2. If unsuccessful, return -1 and set errno. */
+
+ptrdiff_t
+mkancesdirs (char *file, struct savewd *wd,
+ int (*make_dir) (char const *, char const *, void *),
+ void *make_dir_arg)
+{
+ /* Address of the previous directory separator that follows an
+ ordinary byte in a file name in the left-to-right scan, or NULL
+ if no such separator precedes the current location P. */
+ char *sep = NULL;
+
+ /* Address of the leftmost file name component that has not yet
+ been processed. */
+ char *component = file;
+
+ char *p = file + FILE_SYSTEM_PREFIX_LEN (file);
+ char c;
+ bool made_dir = false;
+
+ /* Scan forward through FILE, creating and chdiring into directories
+ along the way. Try MAKE_DIR before chdir, so that the procedure
+ works even when two or more processes are executing it in
+ parallel. Isolate each file name component by having COMPONENT
+ point to its start and SEP point just after its end. */
+
+ while ((c = *p++))
+ if (ISSLASH (*p))
+ {
+ if (! ISSLASH (c))
+ sep = p;
+ }
+ else if (ISSLASH (c) && *p && sep)
+ {
+ /* Don't bother to make or test for "." since it does not
+ affect the algorithm. */
+ if (! (sep - component == 1 && component[0] == '.'))
+ {
+ int make_dir_errno = 0;
+ int savewd_chdir_options = 0;
+ int chdir_result;
+
+ /* Temporarily modify FILE to isolate this file name
+ component. */
+ *sep = '\0';
+
+ /* Invoke MAKE_DIR on this component, except don't bother
+ with ".." since it must exist if its "parent" does. */
+ if (sep - component == 2
+ && component[0] == '.' && component[1] == '.')
+ made_dir = false;
+ else
+ switch (make_dir (file, component, make_dir_arg))
+ {
+ case -1:
+ make_dir_errno = errno;
+ break;
+
+ case 0:
+ savewd_chdir_options |= SAVEWD_CHDIR_READABLE;
+ /* Fall through. */
+ case 1:
+ made_dir = true;
+ break;
+ }
+
+ if (made_dir)
+ savewd_chdir_options |= SAVEWD_CHDIR_NOFOLLOW;
+
+ chdir_result =
+ savewd_chdir (wd, component, savewd_chdir_options, NULL);
+
+ /* Undo the temporary modification to FILE, unless there
+ was a failure. */
+ if (chdir_result != -1)
+ *sep = '/';
+
+ if (chdir_result != 0)
+ {
+ if (make_dir_errno != 0 && errno == ENOENT)
+ errno = make_dir_errno;
+ return chdir_result;
+ }
+ }
+
+ component = p;
+ }
+
+ return component - file;
+}
Index: mkancesdirs.h
===================================================================
RCS file: mkancesdirs.h
diff -N mkancesdirs.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mkancesdirs.h 24 Aug 2007 18:06:24 -0000 1.1
@@ -0,0 +1,4 @@
+#include <stddef.h>
+struct savewd;
+ptrdiff_t mkancesdirs (char *, struct savewd *,
+ int (*) (char const *, char const *, void *), void *);
Index: mkdir-p.c
===================================================================
RCS file: mkdir-p.c
diff -N mkdir-p.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mkdir-p.c 24 Aug 2007 18:06:24 -0000 1.1
@@ -0,0 +1,209 @@
+/* mkdir-p.c -- Ensure that a directory and its parents exist.
+
+ Copyright (C) 1990, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
+ 2006, 2007 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 program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Paul Eggert, David MacKenzie, and Jim Meyering. */
+
+#include <config.h>
+
+#include "mkdir-p.h"
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
+#include "dirchownmod.h"
+#include "dirname.h"
+#include "error.h"
+#include "quote.h"
+#include "mkancesdirs.h"
+#include "savewd.h"
+
+#ifndef HAVE_FCHMOD
+# define HAVE_FCHMOD false
+#endif
+
+/* Ensure that the directory DIR exists.
+
+ WD is the working directory, as in savewd.c.
+
+ If MAKE_ANCESTOR is not null, create any ancestor directories that
+ don't already exist, by invoking MAKE_ANCESTOR (DIR, ANCESTOR, OPTIONS).
+ This function should return zero if successful, -1 (setting errno)
+ otherwise. In this case, DIR may be modified by storing '\0' bytes
+ into it, to access the ancestor directories, and this modification
+ is retained on return if the ancestor directories could not be
+ created.
+
+ Create DIR as a new directory with using mkdir with permissions
+ MODE. It is also OK if MAKE_ANCESTOR is not null and a
+ directory DIR already exists.
+
+ Call ANNOUNCE (DIR, OPTIONS) just after successfully making DIR,
+ even if some of the following actions fail.
+
+ Set DIR's owner to OWNER and group to GROUP, but leave the owner
+ alone if OWNER is (uid_t) -1, and similarly for GROUP.
+
+ Set DIR's mode bits to MODE, except preserve any of the bits that
+ correspond to zero bits in MODE_BITS. In other words, MODE_BITS is
+ a mask that specifies which of DIR's mode bits should be set or
+ cleared. MODE should be a subset of MODE_BITS, which in turn
+ should be a subset of CHMOD_MODE_BITS. Changing the mode in this
+ way is necessary if DIR already existed or if MODE and MODE_BITS
+ specify non-permissions bits like S_ISUID.
+
+ However, if PRESERVE_EXISTING is true and DIR already exists,
+ do not attempt to set DIR's ownership and file mode bits.
+
+ This implementation assumes the current umask is zero.
+
+ Return true if DIR exists as a directory with the proper ownership
+ and file mode bits when done, or if a child process has been
+ dispatched to do the real work (though the child process may not
+ have finished yet -- it is the caller's responsibility to handle
+ this). Report a diagnostic and return false on failure, storing
+ '\0' into *DIR if an ancestor directory had problems. */
+
+bool
+make_dir_parents (char *dir,
+ struct savewd *wd,
+ int (*make_ancestor) (char const *, char const *, void *),
+ void *options,
+ mode_t mode,
+ void (*announce) (char const *, void *),
+ mode_t mode_bits,
+ uid_t owner,
+ gid_t group,
+ bool preserve_existing)
+{
+ int mkdir_errno = (IS_ABSOLUTE_FILE_NAME (dir) ? 0 : savewd_errno (wd));
+
+ if (mkdir_errno == 0)
+ {
+ ptrdiff_t prefix_len = 0;
+ int savewd_chdir_options = (HAVE_FCHMOD ? SAVEWD_CHDIR_SKIP_READABLE :
0);
+
+ if (make_ancestor)
+ {
+ prefix_len = mkancesdirs (dir, wd, make_ancestor, options);
+ if (prefix_len < 0)
+ {
+ if (prefix_len < -1)
+ return true;
+ mkdir_errno = errno;
+ }
+ }
+
+ if (0 <= prefix_len)
+ {
+ /* If the ownership might change, or if the directory will be
+ writeable to other users and its special mode bits may
+ change after the directory is created, create it with
+ more restrictive permissions at first, so unauthorized
+ users cannot nip in before the directory is ready. */
+ bool keep_owner = owner == (uid_t) -1 && group == (gid_t) -1;
+ bool keep_special_mode_bits =
+ ((mode_bits & (S_ISUID | S_ISGID)) | (mode & S_ISVTX)) == 0;
+ mode_t mkdir_mode = mode;
+ if (! keep_owner)
+ mkdir_mode &= ~ (S_IRWXG | S_IRWXO);
+ else if (! keep_special_mode_bits)
+ mkdir_mode &= ~ (S_IWGRP | S_IWOTH);
+
+ if (mkdir (dir + prefix_len, mkdir_mode) == 0)
+ {
+ announce (dir, options);
+ preserve_existing = keep_owner & keep_special_mode_bits;
+ savewd_chdir_options |=
+ (SAVEWD_CHDIR_NOFOLLOW
+ | (mode & S_IRUSR ? SAVEWD_CHDIR_READABLE : 0));
+ }
+ else
+ {
+ mkdir_errno = errno;
+ mkdir_mode = -1;
+ }
+
+ if (preserve_existing)
+ {
+ struct stat st;
+ if (mkdir_errno == 0
+ || (mkdir_errno != ENOENT && make_ancestor
+ && stat (dir + prefix_len, &st) == 0
+ && S_ISDIR (st.st_mode)))
+ return true;
+ }
+ else
+ {
+ int open_result[2];
+ int chdir_result =
+ savewd_chdir (wd, dir + prefix_len,
+ savewd_chdir_options, open_result);
+ if (chdir_result < -1)
+ return true;
+ else
+ {
+ bool chdir_ok = (chdir_result == 0);
+ int chdir_errno = errno;
+ int fd = open_result[0];
+ bool chdir_failed_unexpectedly =
+ (mkdir_errno == 0
+ && ((! chdir_ok && (mode & S_IXUSR))
+ || (fd < 0 && (mode & S_IRUSR))));
+
+ if (chdir_failed_unexpectedly)
+ {
+ /* No need to save errno here; it's irrelevant. */
+ if (0 <= fd)
+ close (fd);
+ }
+ else
+ {
+ char const *subdir = (chdir_ok ? "." : dir + prefix_len);
+ if (dirchownmod (fd, subdir, mkdir_mode, owner, group,
+ mode, mode_bits)
+ == 0)
+ return true;
+ }
+
+ if (mkdir_errno == 0
+ || (mkdir_errno != ENOENT && make_ancestor
+ && errno != ENOTDIR))
+ {
+ error (0,
+ (! chdir_failed_unexpectedly ? errno
+ : ! chdir_ok && (mode & S_IXUSR) ? chdir_errno
+ : open_result[1]),
+ _(keep_owner
+ ? "cannot change permissions of %s"
+ : "cannot change owner and permissions of %s"),
+ quote (dir));
+ return false;
+ }
+ }
+ }
+ }
+ }
+
+ error (0, mkdir_errno, _("cannot create directory %s"), quote (dir));
+ return false;
+}
Index: mkdir-p.h
===================================================================
RCS file: mkdir-p.h
diff -N mkdir-p.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mkdir-p.h 24 Aug 2007 18:06:24 -0000 1.1
@@ -0,0 +1,36 @@
+/* mkdir-p.h -- Ensure that a directory and its parents exist.
+
+ Copyright (C) 1994, 1995, 1996, 1997, 2000, 2003, 2004, 2005, 2006
+ 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 program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Paul Eggert, David MacKenzie, and Jim Meyering. */
+
+#include <stdbool.h>
+#include <sys/types.h>
+
+struct savewd;
+bool make_dir_parents (char *dir,
+ struct savewd *wd,
+ int (*make_ancestor) (char const *, char const *,
+ void *),
+ void *options,
+ mode_t mode,
+ void (*announce) (char const *, void *),
+ mode_t mode_bits,
+ uid_t owner,
+ gid_t group,
+ bool preserve_existing);
Index: quote.c
===================================================================
RCS file: quote.c
diff -N quote.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ quote.c 24 Aug 2007 18:06:24 -0000 1.1
@@ -0,0 +1,41 @@
+/* quote.c - quote arguments for output
+
+ Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005, 2006 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 program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Paul Eggert <address@hidden> */
+
+#include <config.h>
+
+#include "quotearg.h"
+#include "quote.h"
+
+/* Return an unambiguous printable representation of NAME,
+ allocated in slot N, suitable for diagnostics. */
+char const *
+quote_n (int n, char const *name)
+{
+ return quotearg_n_style (n, locale_quoting_style, name);
+}
+
+/* Return an unambiguous printable representation of NAME,
+ suitable for diagnostics. */
+char const *
+quote (char const *name)
+{
+ return quote_n (0, name);
+}
Index: quote.h
===================================================================
RCS file: quote.h
diff -N quote.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ quote.h 24 Aug 2007 18:06:24 -0000 1.1
@@ -0,0 +1,22 @@
+/* quote.h - prototypes for quote.c
+
+ Copyright (C) 1998, 1999, 2000, 2001, 2003 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 program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+
+char const *quote_n (int n, char const *name);
+char const *quote (char const *name);
Index: raise.c
===================================================================
RCS file: raise.c
diff -N raise.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ raise.c 24 Aug 2007 18:06:24 -0000 1.1
@@ -0,0 +1,31 @@
+/* Provide a non-threads replacement for the POSIX raise function.
+
+ Copyright (C) 2002, 2003, 2005, 2006 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 program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* written by Jim Meyering */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <signal.h>
+#include <unistd.h>
+
+int
+raise (int sig)
+{
+ return kill (getpid (), sig);
+}
Index: savewd.c
===================================================================
RCS file: savewd.c
diff -N savewd.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ savewd.c 24 Aug 2007 18:06:24 -0000 1.1
@@ -0,0 +1,307 @@
+/* Save and restore the working directory, possibly using a child process.
+
+ Copyright (C) 2006, 2007 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 program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Paul Eggert. */
+
+#include <config.h>
+
+#include "savewd.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "dirname.h"
+#include "fcntl-safer.h"
+
+
+/* Save the working directory into *WD, if it hasn't been saved
+ already. Return true if a child has been forked to do the real
+ work. */
+static bool
+savewd_save (struct savewd *wd)
+{
+ switch (wd->state)
+ {
+ case INITIAL_STATE:
+ /* Save the working directory, or prepare to fall back if possible. */
+ {
+ int fd = open_safer (".", O_RDONLY);
+ if (0 <= fd)
+ {
+ wd->state = FD_STATE;
+ wd->val.fd = fd;
+ break;
+ }
+ if (errno != EACCES && errno != ESTALE)
+ {
+ wd->state = ERROR_STATE;
+ wd->val.errnum = errno;
+ break;
+ }
+ }
+ wd->state = FORKING_STATE;
+ wd->val.child = -1;
+ /* Fall through. */
+ case FORKING_STATE:
+ if (wd->val.child < 0)
+ {
+ /* "Save" the initial working directory by forking a new
+ subprocess that will attempt all the work from the chdir
+ until until the next savewd_restore. */
+ wd->val.child = fork ();
+ if (wd->val.child != 0)
+ {
+ if (0 < wd->val.child)
+ return true;
+ wd->state = ERROR_STATE;
+ wd->val.errnum = errno;
+ }
+ }
+ break;
+
+ case FD_STATE:
+ case FD_POST_CHDIR_STATE:
+ case ERROR_STATE:
+ case FINAL_STATE:
+ break;
+
+ default:
+ assert (false);
+ }
+
+ return false;
+}
+
+int
+savewd_chdir (struct savewd *wd, char const *dir, int options,
+ int open_result[2])
+{
+ int fd = -1;
+ int result = 0;
+
+ /* Open the directory if requested, or if avoiding a race condition
+ is requested and possible. */
+ if (open_result
+ || (options & (HAVE_WORKING_O_NOFOLLOW ? SAVEWD_CHDIR_NOFOLLOW : 0)))
+ {
+ fd = open (dir,
+ (O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK
+ | (options & SAVEWD_CHDIR_NOFOLLOW ? O_NOFOLLOW : 0)));
+
+ if (open_result)
+ {
+ open_result[0] = fd;
+ open_result[1] = errno;
+ }
+
+ if (fd < 0 && (errno != EACCES || (options & SAVEWD_CHDIR_READABLE)))
+ result = -1;
+ }
+
+ if (result == 0 && ! (0 <= fd && options & SAVEWD_CHDIR_SKIP_READABLE))
+ {
+ if (savewd_save (wd))
+ {
+ open_result = NULL;
+ result = -2;
+ }
+ else
+ {
+ result = (fd < 0 ? chdir (dir) : fchdir (fd));
+
+ if (result == 0)
+ switch (wd->state)
+ {
+ case FD_STATE:
+ wd->state = FD_POST_CHDIR_STATE;
+ break;
+
+ case ERROR_STATE:
+ case FD_POST_CHDIR_STATE:
+ case FINAL_STATE:
+ break;
+
+ case FORKING_STATE:
+ assert (wd->val.child == 0);
+ break;
+
+ default:
+ assert (false);
+ }
+ }
+ }
+
+ if (0 <= fd && ! open_result)
+ {
+ int e = errno;
+ close (fd);
+ errno = e;
+ }
+
+ return result;
+}
+
+int
+savewd_restore (struct savewd *wd, int status)
+{
+ switch (wd->state)
+ {
+ case INITIAL_STATE:
+ case FD_STATE:
+ /* The working directory is the desired directory, so there's no
+ work to do. */
+ break;
+
+ case FD_POST_CHDIR_STATE:
+ /* Restore the working directory using fchdir. */
+ if (fchdir (wd->val.fd) == 0)
+ {
+ wd->state = FD_STATE;
+ break;
+ }
+ else
+ {
+ int chdir_errno = errno;
+ close (wd->val.fd);
+ wd->state = ERROR_STATE;
+ wd->val.errnum = chdir_errno;
+ }
+ /* Fall through. */
+ case ERROR_STATE:
+ /* Report an error if asked to restore the working directory. */
+ errno = wd->val.errnum;
+ return -1;
+
+ case FORKING_STATE:
+ /* "Restore" the working directory by waiting for the subprocess
+ to finish. */
+ {
+ pid_t child = wd->val.child;
+ if (child == 0)
+ _exit (status);
+ if (0 < child)
+ {
+ int child_status;
+ while (waitpid (child, &child_status, 0) < 0)
+ assert (errno == EINTR);
+ wd->val.child = -1;
+ if (! WIFEXITED (child_status))
+ raise (WTERMSIG (child_status));
+ return WEXITSTATUS (child_status);
+ }
+ }
+ break;
+
+ default:
+ assert (false);
+ }
+
+ return 0;
+}
+
+void
+savewd_finish (struct savewd *wd)
+{
+ switch (wd->state)
+ {
+ case INITIAL_STATE:
+ case ERROR_STATE:
+ break;
+
+ case FD_STATE:
+ case FD_POST_CHDIR_STATE:
+ close (wd->val.fd);
+ break;
+
+ case FORKING_STATE:
+ assert (wd->val.child < 0);
+ break;
+
+ default:
+ assert (false);
+ }
+
+ wd->state = FINAL_STATE;
+}
+
+/* Return true if the actual work is currently being done by a
+ subprocess.
+
+ A true return means that the caller and the subprocess should
+ resynchronize later with savewd_restore, using only their own
+ memory to decide when to resynchronize; they should not consult the
+ file system to decide, because that might lead to race conditions.
+ This is why savewd_chdir is broken out into another function;
+ savewd_chdir's callers _can_ inspect the file system to decide
+ whether to call savewd_chdir. */
+static inline bool
+savewd_delegating (struct savewd const *wd)
+{
+ return wd->state == FORKING_STATE && 0 < wd->val.child;
+}
+
+int
+savewd_process_files (int n_files, char **file,
+ int (*act) (char *, struct savewd *, void *),
+ void *options)
+{
+ int i = 0;
+ int last_relative;
+ int exit_status = EXIT_SUCCESS;
+ struct savewd wd;
+ savewd_init (&wd);
+
+ for (last_relative = n_files - 1; 0 <= last_relative; last_relative--)
+ if (! IS_ABSOLUTE_FILE_NAME (file[last_relative]))
+ break;
+
+ for (; i < last_relative; i++)
+ {
+ if (! savewd_delegating (&wd))
+ {
+ int s = act (file[i], &wd, options);
+ if (exit_status < s)
+ exit_status = s;
+ }
+
+ if (! IS_ABSOLUTE_FILE_NAME (file[i + 1]))
+ {
+ int r = savewd_restore (&wd, exit_status);
+ if (exit_status < r)
+ exit_status = r;
+ }
+ }
+
+ savewd_finish (&wd);
+
+ for (; i < n_files; i++)
+ {
+ int s = act (file[i], &wd, options);
+ if (exit_status < s)
+ exit_status = s;
+ }
+
+ return exit_status;
+}
Index: savewd.h
===================================================================
RCS file: savewd.h
diff -N savewd.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ savewd.h 24 Aug 2007 18:06:24 -0000 1.1
@@ -0,0 +1,149 @@
+/* Save and restore the working directory, possibly using a subprocess.
+
+ Copyright (C) 2006 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 program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+
+/* Written by Paul Eggert. */
+
+#ifndef SAVEWD_H
+# define SAVEWD_H 1
+
+#include <stdbool.h>
+#include <sys/types.h>
+
+/* A saved working directory. The member names and constants defined
+ by this structure are private to the savewd module. */
+struct savewd
+{
+ /* The state of this object. */
+ enum
+ {
+ /* This object has been created but does not yet represent
+ the working directory. */
+ INITIAL_STATE,
+
+ /* val.fd is the original working directory's file descriptor.
+ It is still the working directory. */
+ FD_STATE,
+
+ /* Like FD_STATE, but the working directory has changed, so
+ restoring it will require a fchdir. */
+ FD_POST_CHDIR_STATE,
+
+ /* Fork and let the subprocess do the work. val.child is 0 in a
+ child, negative in a childless parent, and the child process
+ ID in a parent with a child. */
+ FORKING_STATE,
+
+ /* A serious problem argues against further efforts. val.errnum
+ contains the error number (e.g., EIO). */
+ ERROR_STATE,
+
+ /* savewd_finish has been called, so the application no longer
+ cares whether the working directory is saved, and there is no
+ more work to do. */
+ FINAL_STATE
+ } state;
+
+ /* The object's value. */
+ union
+ {
+ int fd;
+ int errnum;
+ pid_t child;
+ } val;
+};
+
+/* Initialize a saved working directory object. */
+static inline void
+savewd_init (struct savewd *wd)
+{
+ wd->state = INITIAL_STATE;
+}
+
+
+/* Options for savewd_chdir. */
+enum
+ {
+ /* Do not follow symbolic links, if supported. */
+ SAVEWD_CHDIR_NOFOLLOW = 1,
+
+ /* The directory should be readable, so fail if it happens to be
+ discovered that the directory is not readable. (Unreadable
+ directories are not necessarily diagnosed, though.) */
+ SAVEWD_CHDIR_READABLE = 2,
+
+ /* Do not chdir if the directory is readable; simply succeed
+ without invoking chdir if the directory was opened. */
+ SAVEWD_CHDIR_SKIP_READABLE = 4
+ };
+
+/* Change the directory, and if successful, record into *WD the fact
+ that the process chdired into DIR. A process using this module
+ should use savewd_chdir rather than chdir or fchdir. Obey the
+ options specified in OPTIONS.
+
+ If OPEN_RESULT is not null, store into OPEN_RESULT[0] a file
+ descriptor that accesses DIR if a file descriptor is successfully
+ obtained. Store -1 otherwise, setting OPEN_RESULT[1] to the error
+ number. Store through OPEN_RESULT regardless of whether the chdir
+ is successful. However, when -2 is returned, the contents of
+ OPEN_RESULT are indeterminate since the file descriptor is closed
+ in the parent.
+
+ Return -2 if a subprocess was spun off to do the real work, -1
+ (setting errno) if unsuccessful, 0 if successful. */
+int savewd_chdir (struct savewd *wd, char const *dir, int options,
+ int open_result[2]);
+
+/* Restore the working directory from *WD. STATUS indicates the exit
+ status corresponding to the work done since the last save; this is
+ used when the caller is in a subprocess. Return 0 if successful,
+ -1 (setting errno) on our failure, a positive subprocess exit
+ status if the working directory was restored in the parent but the
+ subprocess failed. */
+int savewd_restore (struct savewd *wd, int status);
+
+/* Return WD's error number, or 0 if WD is not in an error state. */
+static inline int
+savewd_errno (struct savewd const *wd)
+{
+ return (wd->state == ERROR_STATE ? wd->val.errnum : 0);
+}
+
+/* Deallocate any resources associated with WD. A program that chdirs
+ should restore before finishing. */
+void savewd_finish (struct savewd *wd);
+
+/* Process N_FILES file names, FILE[0] through FILE[N_FILES - 1].
+ For each file name F, call ACT (F, WD, OPTIONS); ACT should invoke
+ savewd_chdir as needed, and should return an exit status. WD
+ represents the working directory; it may be in an error state when
+ ACT is called.
+
+ Save and restore the working directory as needed by the file name
+ vector; assume that ACT does not require access to any relative
+ file names other than its first argument, and that it is OK if the
+ working directory is changed when this function returns. Some
+ actions may be applied in a subprocess.
+
+ Return the maximum exit status that any call to ACT returned, or
+ EXIT_SUCCESS (i.e., 0) if no calls were made. */
+int savewd_process_files (int n_files, char **file,
+ int (*act) (char *, struct savewd *, void *),
+ void *options);
+
+#endif