/* mkfifo -- make fifo's (named pipes)                                          This is the mkfifo utility
   Copyright (C) 1990-2018 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 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               
   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, see <https://www.gnu.org/licenses/>.  */   The GNUv3 license
                                                                                
/* David MacKenzie <djm@ai.mit.edu>  */                                         
                                                                                
#include <config.h>                                                             Provides system specific information
#include <stdio.h>                                                              Provides standard I/O capability
#include <getopt.h>                                                             ...!includes auto-comment...
#include <sys/types.h>                                                          Provides system data types
#include <selinux/selinux.h>                                                    ...!includes auto-comment......!includes auto-comment...
                                                                                
#include "system.h"                                                             ...!includes auto-comment...
#include "die.h"                                                                ...!includes auto-comment...
#include "error.h"                                                              ...!includes auto-comment...
#include "modechange.h"                                                         ...!includes auto-comment...
#include "quote.h"                                                              ...!includes auto-comment...
#include "selinux.h"                                                            ...!includes auto-comment...
#include "smack.h"                                                              ...!includes auto-comment...
                                                                                
/* The official name of this program (e.g., no 'g' prefix).  */                 
#define PROGRAM_NAME "mkfifo"                                                   Line 34
                                                                                
#define AUTHORS proper_name ("David MacKenzie")                                 Line 36
                                                                                
static struct option const longopts[] =                                         Line 38
{                                                                               
  {GETOPT_SELINUX_CONTEXT_OPTION_DECL},                                         Line 40
  {"mode", required_argument, NULL, 'm'},                                       Line 41
  {GETOPT_HELP_OPTION_DECL},                                                    Line 42
  {GETOPT_VERSION_OPTION_DECL},                                                 Line 43
  {NULL, 0, NULL, 0}                                                            Line 44
};                                                                              Block 1
                                                                                
void                                                                            Line 47
usage (int status)                                                              Line 48
{                                                                               
  if (status != EXIT_SUCCESS)                                                   Line 50
    emit_try_help ();                                                           ...!common auto-comment...
  else                                                                          Line 52
    {                                                                           
      printf (_("Usage: %s [OPTION]... NAME...\n"), program_name);              Line 54
      fputs (_("\                                                               Line 55
Create named pipes (FIFOs) with the given NAMEs.\n\                             Line 56
"), stdout);                                                                    Line 57
                                                                                
      emit_mandatory_arg_note ();                                               ...!common auto-comment...
                                                                                
      fputs (_("\                                                               Line 61
  -m, --mode=MODE    set file permission bits to MODE, not a=rw - umask\n\      Line 62
"), stdout);                                                                    Line 63
      fputs (_("\                                                               Line 64
  -Z                   set the SELinux security context to default type\n\      Line 65
      --context[=CTX]  like -Z, or if CTX is specified then set the SELinux\n\  Line 66
                         or SMACK security context to CTX\n\                    Line 67
"), stdout);                                                                    Line 68
      fputs (HELP_OPTION_DESCRIPTION, stdout);                                  Line 69
      fputs (VERSION_OPTION_DESCRIPTION, stdout);                               Line 70
      emit_ancillary_info (PROGRAM_NAME);                                       Line 71
    }                                                                           
  exit (status);                                                                Line 73
}                                                                               Block 2
                                                                                
int                                                                             
main (int argc, char **argv)                                                    Line 77
{                                                                               
  mode_t newmode;                                                               Line 79
  char const *specified_mode = NULL;                                            Line 80
  int exit_status = EXIT_SUCCESS;                                               Line 81
  int optc;                                                                     Line 82
  char const *scontext = NULL;                                                  Line 83
  bool set_security_context = false;                                            Line 84
                                                                                
  initialize_main (&argc, &argv);                                               VMS-specific entry point handling wildcard expansion
  set_program_name (argv[0]);                                                   Retains program name and discards path
  setlocale (LC_ALL, "");                                                       Sets up internationalization (i18n)
  bindtextdomain (PACKAGE, LOCALEDIR);                                          Assigns i18n directorySets text domain for _() [gettext()] function
  textdomain (PACKAGE);                                                         Sets text domain for _() [gettext()] function
                                                                                
  atexit (close_stdout);                                                        Close stdout on exit (see gnulib)
                                                                                
  while ((optc = getopt_long (argc, argv, "m:Z", longopts, NULL)) != -1)        Line 94
    {                                                                           
      switch (optc)                                                             Line 96
        {                                                                       
        case 'm':                                                               Line 98
          specified_mode = optarg;                                              Line 99
          break;                                                                Line 100
        case 'Z':                                                               Line 101
          if (is_smack_enabled ())                                              ...!common auto-comment...
            {                                                                   
              /* We don't yet support -Z to restore context with SMACK.  */     
              scontext = optarg;                                                Line 105
            }                                                                   
          else if (is_selinux_enabled () > 0)                                   ...!common auto-comment...
            {                                                                   
              if (optarg)                                                       Line 109
                scontext = optarg;                                              Line 110
              else                                                              Line 111
                set_security_context = true;                                    Line 112
            }                                                                   
          else if (optarg)                                                      Line 114
            {                                                                   
              error (0, 0,                                                      Line 116
                     _("warning: ignoring --context; "                          Line 117
                       "it requires an SELinux/SMACK-enabled kernel"));         Line 118
            }                                                                   
          break;                                                                Line 120
        case_GETOPT_HELP_CHAR;                                                  Line 121
        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);                       Line 122
        default:                                                                Line 123
          usage (EXIT_FAILURE);                                                 Line 124
        }                                                                       
    }                                                                           
                                                                                
  if (optind == argc)                                                           Line 128
    {                                                                           
      error (0, 0, _("missing operand"));                                       Line 130
      usage (EXIT_FAILURE);                                                     Line 131
    }                                                                           
                                                                                
  if (scontext)                                                                 Line 134
    {                                                                           
      int ret = 0;                                                              Line 136
      if (is_smack_enabled ())                                                  ...!common auto-comment...
        ret = smack_set_label_for_self (scontext);                              Line 138
      else                                                                      Line 139
        ret = setfscreatecon (se_const (scontext));                             Line 140
                                                                                
      if (ret < 0)                                                              Line 142
        die (EXIT_FAILURE, errno,                                               Line 143
             _("failed to set default file creation context to %s"),            Line 144
             quote (scontext));                                                 Line 145
    }                                                                           
                                                                                
  newmode = MODE_RW_UGO;                                                        Line 148
  if (specified_mode)                                                           Line 149
    {                                                                           
      mode_t umask_value;                                                       Line 151
      struct mode_change *change = mode_compile (specified_mode);               Line 152
      if (!change)                                                              Line 153
        die (EXIT_FAILURE, 0, _("invalid mode"));                               Line 154
      umask_value = umask (0);                                                  Line 155
      umask (umask_value);                                                      Line 156
      newmode = mode_adjust (newmode, false, umask_value, change, NULL);        Line 157
      free (change);                                                            Line 158
      if (newmode & ~S_IRWXUGO)                                                 Line 159
        die (EXIT_FAILURE, 0,                                                   Line 160
             _("mode must specify only file permission bits"));                 Line 161
    }                                                                           
                                                                                
  for (; optind < argc; ++optind)                                               Line 164
    {                                                                           
      if (set_security_context)                                                 Line 166
        defaultcon (argv[optind], S_IFIFO);                                     Line 167
      if (mkfifo (argv[optind], newmode) != 0)                                  Line 168
        {                                                                       
          error (0, errno, _("cannot create fifo %s"), quoteaf (argv[optind])); Line 170
          exit_status = EXIT_FAILURE;                                           Line 171
        }                                                                       
      else if (specified_mode && lchmod (argv[optind], newmode) != 0)           Line 173
        {                                                                       
          error (0, errno, _("cannot set permissions of %s"),                   Line 175
                 quoteaf (argv[optind]));                                       Line 176
          exit_status = EXIT_FAILURE;                                           Line 177
        }                                                                       
    }                                                                           
                                                                                
  return exit_status;                                                           Line 181
}                                                                               Block 3