New module 'unicase/u16-ct-tolower'.
[gnulib.git] / lib / modechange.c
index 51684a4..1296717 100644 (file)
@@ -3,10 +3,10 @@
    Copyright (C) 1989, 1990, 1997, 1998, 1999, 2001, 2003, 2004, 2005,
    2006 Free Software Foundation, Inc.
 
    Copyright (C) 1989, 1990, 1997, 1998, 1999, 2001, 2003, 2004, 2005,
    2006 Free Software Foundation, Inc.
 
-   This program is free software; you can redistribute it and/or modify
+   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
    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.
+   the Free Software Foundation; either version 3 of the License, 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
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -14,8 +14,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    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.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* Written by David MacKenzie <djm@ai.mit.edu> */
 
 
 /* Written by David MacKenzie <djm@ai.mit.edu> */
 
@@ -26,9 +25,7 @@
    changing the mode of many files, this probably results in a
    performance gain.  */
 
    changing the mode of many files, this probably results in a
    performance gain.  */
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
+#include <config.h>
 
 #include "modechange.h"
 #include <sys/stat.h>
 
 #include "modechange.h"
 #include <sys/stat.h>
@@ -143,12 +140,12 @@ mode_compile (char const *mode_string)
   if ('0' <= *mode_string && *mode_string < '8')
     {
       unsigned int octal_mode = 0;
   if ('0' <= *mode_string && *mode_string < '8')
     {
       unsigned int octal_mode = 0;
-      unsigned int octal_mentioned = 0;
+      mode_t mode;
+      mode_t mentioned;
 
       do
        {
          octal_mode = 8 * octal_mode + *mode_string++ - '0';
 
       do
        {
          octal_mode = 8 * octal_mode + *mode_string++ - '0';
-         octal_mentioned = 8 * octal_mentioned + 7;
          if (ALLM < octal_mode)
            return NULL;
        }
          if (ALLM < octal_mode)
            return NULL;
        }
@@ -157,8 +154,9 @@ mode_compile (char const *mode_string)
       if (*mode_string)
        return NULL;
 
       if (*mode_string)
        return NULL;
 
-      return make_node_op_equals (octal_to_mode (octal_mode),
-                                 octal_to_mode (octal_mentioned & ALLM));
+      mode = octal_to_mode (octal_mode);
+      mentioned = (mode & (S_ISUID | S_ISGID)) | S_ISVTX | S_IRWXUGO;
+      return make_node_op_equals (mode, mentioned);
     }
 
   /* Allocate enough space to hold the result.  */
     }
 
   /* Allocate enough space to hold the result.  */
@@ -299,7 +297,8 @@ mode_create_from_ref (const char *ref_file)
    directory if DIR), assuming the umask is UMASK_VALUE, adjusted as
    indicated by the list of change operations CHANGES.  If DIR, the
    type 'X' change affects the returned value even if no execute bits
    directory if DIR), assuming the umask is UMASK_VALUE, adjusted as
    indicated by the list of change operations CHANGES.  If DIR, the
    type 'X' change affects the returned value even if no execute bits
-   were set in OLDMODE.  If PMODE_BITS is not null, store into
+   were set in OLDMODE, and set user and group ID bits are preserved
+   unless CHANGES mentioned them.  If PMODE_BITS is not null, store into
    *PMODE_BITS a mask denoting file mode bits that are affected by
    CHANGES.
 
    *PMODE_BITS a mask denoting file mode bits that are affected by
    CHANGES.