]> git.ipfire.org Git - thirdparty/bash.git/blobdiff - builtins/umask.def
Imported from ../bash-2.05.tar.gz.
[thirdparty/bash.git] / builtins / umask.def
index 5ef8f3b7ff4b652a494a98f8ddbbe345a1af56ae..1c1591e05def7b2fa76497df800babaccbaaf8f7 100644 (file)
@@ -7,7 +7,7 @@ This file is part of GNU Bash, the Bourne Again SHell.
 
 Bash 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 1, or (at your option) any later
+Software Foundation; either version 2, or (at your option) any later
 version.
 
 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -17,25 +17,29 @@ for more details.
 
 You should have received a copy of the GNU General Public License along
 with Bash; see the file COPYING.  If not, write to the Free Software
-Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
 
 $PRODUCES umask.c
 
 $BUILTIN umask
 $FUNCTION umask_builtin
-$SHORT_DOC umask [-S] [mode]
+$SHORT_DOC umask [-p] [-S] [mode]
 The user file-creation mask is set to MODE.  If MODE is omitted, or if
 `-S' is supplied, the current value of the mask is printed.  The `-S'
 option makes the output symbolic; otherwise an octal number is output.
-If MODE begins with a digit, it is interpreted as an octal number,
-otherwise it is a symbolic mode string like that accepted by chmod(1).
+If `-p' is supplied, and MODE is omitted, the output is in a form
+that may be used as input.  If MODE begins with a digit, it is
+interpreted as an octal number, otherwise it is a symbolic mode string
+like that accepted by chmod(1).
 $END
 
 #include <config.h>
 
 #include "../bashtypes.h"
-#include "../filecntl.h"
-#include <sys/file.h>
+#include "filecntl.h"
+#ifndef _MINIX
+#  include <sys/file.h>
+#endif
 
 #if defined (HAVE_UNISTD_H)
 #include <unistd.h>
@@ -44,7 +48,7 @@ $END
 #include <stdio.h>
 
 #include "../shell.h"
-#include "../posixstat.h"
+#include "posixstat.h"
 #include "common.h"
 #include "bashgetopt.h"
 
@@ -63,17 +67,21 @@ int
 umask_builtin (list)
      WORD_LIST *list;
 {
-  int print_symbolically, opt, umask_value;
+  int print_symbolically, opt, umask_value, pflag;
+  mode_t umask_arg;
 
-  print_symbolically = 0;
+  print_symbolically = pflag = 0;
   reset_internal_getopt ();
-  while ((opt = internal_getopt (list, "S")) != -1)
+  while ((opt = internal_getopt (list, "Sp")) != -1)
     {
       switch (opt)
        {
        case 'S':
          print_symbolically++;
          break;
+       case 'p':
+         pflag++;
+         break;
        default:
          builtin_usage ();
          return (EX_USAGE);
@@ -105,19 +113,22 @@ umask_builtin (list)
          if (umask_value == -1)
            return (EXECUTION_FAILURE);
        }
-      umask (umask_value);
+      umask_arg = (mode_t)umask_value;
+      umask (umask_arg);
       if (print_symbolically)
-       print_symbolic_umask (umask_value);
+       print_symbolic_umask (umask_arg);
     }
   else                         /* Display the UMASK for this user. */
     {
-      umask_value = umask (022);
-      umask (umask_value);
+      umask_arg = umask (022);
+      umask (umask_arg);
 
+      if (pflag)
+       printf ("umask%s ", (print_symbolically ? " -S" : ""));
       if (print_symbolically)
-       print_symbolic_umask (umask_value);
+       print_symbolic_umask (umask_arg);
       else
-       printf ("%03o\n", umask_value);
+       printf ("%03o\n", umask_arg);
     }
 
   fflush (stdout);
@@ -128,7 +139,7 @@ umask_builtin (list)
    printed if the corresponding bit is clear in the umask. */
 static void
 print_symbolic_umask (um)
-     int um;
+     mode_t um;
 {
   char ubits[4], gbits[4], obits[4];           /* u=rwx,g=rwx,o=rwx */
   int i;
@@ -163,51 +174,37 @@ print_symbolic_umask (um)
   printf ("u=%s,g=%s,o=%s\n", ubits, gbits, obits);
 }
 
-/* Set the umask from a symbolic mode string similar to that accepted
-   by chmod.  If the -S argument is given, then print the umask in a
-   symbolic form. */
-static int
-symbolic_umask (list)
-     WORD_LIST *list;
+int
+parse_symbolic_mode (mode, initial_bits)
+     char *mode;
+     int initial_bits;
 {
-  int um, umc, c;
-  int who, op, perm, mask;
+  int who, op, perm, mask, bits, c;
   char *s;
 
-  /* Get the initial umask.  Don't change it yet. */
-  um = umask (022);
-  umask (um);
-
-  /* All work below is done with the complement of the umask -- it's
-     more intuitive and easier to deal with.  It is complemented
-     again before being returned. */
-  umc = ~um;
-
-  s = list->word->word;
-
-  for (;;)
+  for (s = mode, bits = initial_bits;;)
     {
       who = op = perm = mask = 0;
 
       /* Parse the `who' portion of the symbolic mode clause. */
       while (member (*s, "agou"))
-        {
+       {
          switch (c = *s++)
            {
-             case 'u':
-               who |= S_IRWXU;
-               continue;
-             case 'g':
-               who |= S_IRWXG;
-               continue;
-             case 'o':
-               who |= S_IRWXO;
-               continue;
-             case 'a':
-               who |= S_IRWXU | S_IRWXG | S_IRWXO;
-               continue;
-             default:
-               break;
+           case 'u':
+             who |= S_IRWXU;
+             continue;
+           case 'g':
+             who |= S_IRWXG;
+             continue;
+           case 'o':
+             who |= S_IRWXO;
+             continue;
+           case 'a':
+             who |= S_IRWXU | S_IRWXG | S_IRWXO;
+             continue;
+           default:
+             break;
            }
        }
 
@@ -215,13 +212,13 @@ symbolic_umask (list)
       op = *s++;
       switch (op)
        {
-         case '+':
-         case '-':
-         case '=':
-           break;
-         default:
-           builtin_error ("bad symbolic mode operator: %c", op);
-           return (-1);
+       case '+':
+       case '-':
+       case '=':
+         break;
+       default:
+         builtin_error ("bad symbolic mode operator: %c", op);
+         return (-1);
        }
 
       /* Parse out the `perm' section of the symbolic mode clause. */
@@ -231,17 +228,15 @@ symbolic_umask (list)
 
          switch (c)
            {
-             case 'r':
-               perm |= S_IRUGO;
-               break;
-
-             case 'w':
-               perm |= S_IWUGO;
-               break;
-
-             case 'x':
-               perm |= S_IXUGO;
-               break;
+           case 'r':
+             perm |= S_IRUGO;
+             break;
+           case 'w':
+             perm |= S_IWUGO;
+             break;
+           case 'x':
+             perm |= S_IXUGO;
+             break;
            }
        }
 
@@ -254,29 +249,22 @@ symbolic_umask (list)
 
          switch (op)
            {
-             case '+':
-               umc |= perm;
-               break;
-
-             case '-':
-               umc &= ~perm;
-               break;
-
-             case '=':
-               umc &= ~who;
-               umc |= perm;
-               break;
-
-             default:
-               builtin_error ("bad symbolic mode operator: %c", op);
-               return (-1);
-           }
-
-         if (!*s)
-           {
-             um = ~umc & 0777;
+           case '+':
+             bits |= perm;
              break;
+           case '-':
+             bits &= ~perm;
+             break;
+           case '=':
+             bits &= ~who;
+             bits |= perm;
+             break;
+
+           /* No other values are possible. */
            }
+
+         if (*s == '\0')
+           break;
          else
            s++;        /* skip past ',' */
        }
@@ -286,5 +274,30 @@ symbolic_umask (list)
          return (-1);
        }
     }
+
+  return (bits);
+}
+
+/* Set the umask from a symbolic mode string similar to that accepted
+   by chmod.  If the -S argument is given, then print the umask in a
+   symbolic form. */
+static int
+symbolic_umask (list)
+     WORD_LIST *list;
+{
+  int um, bits;
+
+  /* Get the initial umask.  Don't change it yet. */
+  um = umask (022);
+  umask (um);
+
+  /* All work is done with the complement of the umask -- it's
+     more intuitive and easier to deal with.  It is complemented
+     again before being returned. */
+  bits = parse_symbolic_mode (list->word->word, ~um);
+  if (bits == -1)
+    return (-1);
+
+  um = ~bits & 0777;
   return (um);
 }