LCOV - code coverage report
Current view: top level - builtins - umask.def (source / functions) Hit Total Coverage
Test: cov-sh.info Lines: 0 132 0.0 %
Date: 2020-10-29 14:49:55 Functions: 0 4 0.0 %

          Line data    Source code
       1             : This file is umask.def, from which is created umask.c.
       2             : It implements the builtin "umask" in Bash.
       3             : 
       4             : Copyright (C) 1987-2015 Free Software Foundation, Inc.
       5             : 
       6             : This file is part of GNU Bash, the Bourne Again SHell.
       7             : 
       8             : Bash is free software: you can redistribute it and/or modify
       9             : it under the terms of the GNU General Public License as published by
      10             : the Free Software Foundation, either version 3 of the License, or
      11             : (at your option) any later version.
      12             : 
      13             : Bash is distributed in the hope that it will be useful,
      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             : GNU General Public License for more details.
      17             : 
      18             : You should have received a copy of the GNU General Public License
      19             : along with Bash.  If not, see <http://www.gnu.org/licenses/>.
      20             : 
      21             : $PRODUCES umask.c
      22             : 
      23             : $BUILTIN umask
      24             : $FUNCTION umask_builtin
      25             : $SHORT_DOC umask [-p] [-S] [mode]
      26             : Display or set file mode mask.
      27             : 
      28             : Sets the user file-creation mask to MODE.  If MODE is omitted, prints
      29             : the current value of the mask.
      30             : 
      31             : If MODE begins with a digit, it is interpreted as an octal number;
      32             : otherwise it is a symbolic mode string like that accepted by chmod(1).
      33             : 
      34             : Options:
      35             :   -p    if MODE is omitted, output in a form that may be reused as input
      36             :   -S    makes the output symbolic; otherwise an octal number is output
      37             : 
      38             : Exit Status:
      39             : Returns success unless MODE is invalid or an invalid option is given.
      40             : $END
      41             : 
      42             : #include <config.h>
      43             : 
      44             : #include "../bashtypes.h"
      45             : #include "filecntl.h"
      46             : #if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
      47             : #  include <sys/file.h>
      48             : #endif
      49             : 
      50             : #if defined (HAVE_UNISTD_H)
      51             : #include <unistd.h>
      52             : #endif
      53             : 
      54             : #include <stdio.h>
      55             : #include <chartypes.h>
      56             : 
      57             : #include "../bashintl.h"
      58             : 
      59             : #include "../shell.h"
      60             : #include "posixstat.h"
      61             : #include "common.h"
      62             : #include "bashgetopt.h"
      63             : 
      64             : /* **************************************************************** */
      65             : /*                                                                  */
      66             : /*                     UMASK Builtin and Helpers                    */
      67             : /*                                                                  */
      68             : /* **************************************************************** */
      69             : 
      70             : static void print_symbolic_umask __P((mode_t));
      71             : static int symbolic_umask __P((WORD_LIST *));
      72             : 
      73             : /* Set or display the mask used by the system when creating files.  Flag
      74             :    of -S means display the umask in a symbolic mode. */
      75             : int
      76           0 : umask_builtin (list)
      77             :      WORD_LIST *list;
      78             : {
      79           0 :   int print_symbolically, opt, umask_value, pflag;
      80           0 :   mode_t umask_arg;
      81             : 
      82           0 :   print_symbolically = pflag = 0;
      83           0 :   reset_internal_getopt ();
      84           0 :   while ((opt = internal_getopt (list, "Sp")) != -1)
      85             :     {
      86           0 :       switch (opt)
      87             :         {
      88           0 :         case 'S':
      89           0 :           print_symbolically++;
      90           0 :           break;
      91           0 :         case 'p':
      92           0 :           pflag++;
      93           0 :           break;
      94           0 :         CASE_HELPOPT;
      95           0 :         default:
      96           0 :           builtin_usage ();
      97           0 :           return (EX_USAGE);
      98             :         }
      99             :     }
     100             : 
     101           0 :   list = loptend;
     102             : 
     103           0 :   if (list)
     104             :     {
     105           0 :       if (DIGIT (*list->word->word))
     106             :         {
     107           0 :           umask_value = read_octal (list->word->word);
     108             : 
     109             :           /* Note that other shells just let you set the umask to zero
     110             :              by specifying a number out of range.  This is a problem
     111             :              with those shells.  We don't change the umask if the input
     112             :              is lousy. */
     113           0 :           if (umask_value == -1)
     114             :             {
     115           0 :               sh_erange (list->word->word, _("octal number"));
     116           0 :               return (EXECUTION_FAILURE);
     117             :             }
     118             :         }
     119             :       else
     120             :         {
     121           0 :           umask_value = symbolic_umask (list);
     122           0 :           if (umask_value == -1)
     123             :             return (EXECUTION_FAILURE);
     124             :         }
     125           0 :       umask_arg = (mode_t)umask_value;
     126           0 :       umask (umask_arg);
     127           0 :       if (print_symbolically)
     128           0 :         print_symbolic_umask (umask_arg);
     129             :     }
     130             :   else                          /* Display the UMASK for this user. */
     131             :     {
     132           0 :       umask_arg = umask (022);
     133           0 :       umask (umask_arg);
     134             : 
     135           0 :       if (pflag)
     136           0 :         printf ("umask%s ", (print_symbolically ? " -S" : ""));
     137           0 :       if (print_symbolically)
     138           0 :         print_symbolic_umask (umask_arg);
     139             :       else
     140           0 :         printf ("%04lo\n", (unsigned long)umask_arg);
     141             :     }
     142             : 
     143           0 :   return (sh_chkwrite (EXECUTION_SUCCESS));
     144             : }
     145             : 
     146             : /* Print the umask in a symbolic form.  In the output, a letter is
     147             :    printed if the corresponding bit is clear in the umask. */
     148             : static void
     149             : #if defined (__STDC__)
     150           0 : print_symbolic_umask (mode_t um)
     151             : #else
     152             : print_symbolic_umask (um)
     153             :      mode_t um;
     154             : #endif
     155             : {
     156           0 :   char ubits[4], gbits[4], obits[4];            /* u=rwx,g=rwx,o=rwx */
     157           0 :   int i;
     158             : 
     159           0 :   i = 0;
     160           0 :   if ((um & S_IRUSR) == 0)
     161           0 :     ubits[i++] = 'r';
     162           0 :   if ((um & S_IWUSR) == 0)
     163           0 :     ubits[i++] = 'w';
     164           0 :   if ((um & S_IXUSR) == 0)
     165           0 :     ubits[i++] = 'x';
     166           0 :   ubits[i] = '\0';
     167             : 
     168           0 :   i = 0;
     169           0 :   if ((um & S_IRGRP) == 0)
     170           0 :     gbits[i++] = 'r';
     171           0 :   if ((um & S_IWGRP) == 0)
     172           0 :     gbits[i++] = 'w';
     173           0 :   if ((um & S_IXGRP) == 0)
     174           0 :     gbits[i++] = 'x';
     175           0 :   gbits[i] = '\0';
     176             : 
     177           0 :   i = 0;
     178           0 :   if ((um & S_IROTH) == 0)
     179           0 :     obits[i++] = 'r';
     180           0 :   if ((um & S_IWOTH) == 0)
     181           0 :     obits[i++] = 'w';
     182           0 :   if ((um & S_IXOTH) == 0)
     183           0 :     obits[i++] = 'x';
     184           0 :   obits[i] = '\0';
     185             : 
     186           0 :   printf ("u=%s,g=%s,o=%s\n", ubits, gbits, obits);
     187           0 : }
     188             : 
     189             : int
     190           0 : parse_symbolic_mode (mode, initial_bits)
     191             :      char *mode;
     192             :      int initial_bits;
     193             : {
     194           0 :   int who, op, perm, bits, c;
     195           0 :   char *s;
     196             : 
     197           0 :   for (s = mode, bits = initial_bits;;)
     198             :     {
     199           0 :       who = op = perm = 0;
     200             : 
     201             :       /* Parse the `who' portion of the symbolic mode clause. */
     202           0 :       while (member (*s, "agou"))
     203             :         {
     204           0 :           switch (c = *s++)
     205             :             {
     206           0 :             case 'u':
     207           0 :               who |= S_IRWXU;
     208           0 :               continue;
     209           0 :             case 'g':
     210           0 :               who |= S_IRWXG;
     211           0 :               continue;
     212           0 :             case 'o':
     213           0 :               who |= S_IRWXO;
     214           0 :               continue;
     215           0 :             case 'a':
     216           0 :               who |= S_IRWXU | S_IRWXG | S_IRWXO;
     217           0 :               continue;
     218             :             default:
     219             :               break;
     220             :             }
     221             :         }
     222             : 
     223             :       /* The operation is now sitting in *s. */
     224           0 :       op = *s++;
     225           0 :       switch (op)
     226             :         {
     227             :         case '+':
     228             :         case '-':
     229             :         case '=':
     230             :           break;
     231           0 :         default:
     232           0 :           builtin_error (_("`%c': invalid symbolic mode operator"), op);
     233           0 :           return (-1);
     234             :         }
     235             : 
     236             :       /* Parse out the `perm' section of the symbolic mode clause. */
     237           0 :       while (member (*s, "rwx"))
     238             :         {
     239           0 :           c = *s++;
     240             : 
     241           0 :           switch (c)
     242             :             {
     243           0 :             case 'r':
     244           0 :               perm |= S_IRUGO;
     245           0 :               break;
     246           0 :             case 'w':
     247           0 :               perm |= S_IWUGO;
     248           0 :               break;
     249           0 :             case 'x':
     250           0 :               perm |= S_IXUGO;
     251           0 :               break;
     252             :             }
     253             :         }
     254             : 
     255             :       /* Now perform the operation or return an error for a
     256             :          bad permission string. */
     257           0 :       if (!*s || *s == ',')
     258             :         {
     259           0 :           if (who)
     260           0 :             perm &= who;
     261             : 
     262           0 :           switch (op)
     263             :             {
     264           0 :             case '+':
     265           0 :               bits |= perm;
     266           0 :               break;
     267           0 :             case '-':
     268           0 :               bits &= ~perm;
     269           0 :               break;
     270           0 :             case '=':
     271           0 :               if (who == 0)
     272           0 :                 who = S_IRWXU | S_IRWXG | S_IRWXO;
     273           0 :               bits &= ~who;
     274           0 :               bits |= perm;
     275           0 :               break;
     276             : 
     277             :             /* No other values are possible. */
     278             :             }
     279             : 
     280           0 :           if (*s == '\0')
     281             :             break;
     282             :           else
     283           0 :             s++;        /* skip past ',' */
     284             :         }
     285             :       else
     286             :         {
     287           0 :           builtin_error (_("`%c': invalid symbolic mode character"), *s);
     288           0 :           return (-1);
     289             :         }
     290             :     }
     291             : 
     292             :   return (bits);
     293             : }
     294             : 
     295             : /* Set the umask from a symbolic mode string similar to that accepted
     296             :    by chmod.  If the -S argument is given, then print the umask in a
     297             :    symbolic form. */
     298             : static int
     299           0 : symbolic_umask (list)
     300             :      WORD_LIST *list;
     301             : {
     302           0 :   int um, bits;
     303             : 
     304             :   /* Get the initial umask.  Don't change it yet. */
     305           0 :   um = umask (022);
     306           0 :   umask (um);
     307             : 
     308             :   /* All work is done with the complement of the umask -- it's
     309             :      more intuitive and easier to deal with.  It is complemented
     310             :      again before being returned. */
     311           0 :   bits = parse_symbolic_mode (list->word->word, ~um & 0777);
     312           0 :   if (bits == -1)
     313           0 :     return (-1);
     314             : 
     315           0 :   um = ~bits & 0777;
     316           0 :   return (um);
     317             : }

Generated by: LCOV version 1.14.0.6.4058