"Fossies" - the Fresh Open Source Software Archive

Member "shake-1.0/unattr.c" (15 Nov 2014, 4907 Bytes) of package /linux/privat/shake-1.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "unattr.c" see the Fossies "Dox" file reference documentation.

    1 /***************************************************************************/
    2 /*  Copyright (C) 2006-2009 Brice Arnould.                                 */
    3 /*                                                                         */
    4 /*  This file is part of ShaKe.                                            */
    5 /*                                                                         */
    6 /*  ShaKe is free software; you can redistribute it and/or modify          */
    7 /*  it under the terms of the GNU General Public License as published by   */
    8 /*  the Free Software Foundation; either version 3 of the License, or      */
    9 /*  (at your option) any later version.                                    */
   10 /*                                                                         */
   11 /*  This program is distributed in the hope that it will be useful,        */
   12 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of         */
   13 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
   14 /*  GNU General Public License for more details.                           */
   15 /*                                                                         */
   16 /*  You should have received a copy of the GNU General Public License      */
   17 /*  along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
   18 /***************************************************************************/
   19 
   20 /*** unattr: quick and dirty hack to remove unwanted Xattrs ****/
   21 
   22 // TODO : move xattr_* out of this file for portability
   23 
   24 #include <stdlib.h>
   25 #include <assert.h>
   26 #include <errno.h>
   27 #include <error.h>
   28 #include <string.h>
   29 #include <attr/attributes.h>    // flistxattr
   30 #include <sys/types.h>      // open()
   31 #include <sys/stat.h>       // open()
   32 #include <fcntl.h>      // open()
   33 #include <unistd.h>     // close()
   34 #include "linux.h"      // getopt()
   35 
   36 #include "config.h"
   37 #include "executive.h"
   38 void strip (char *name, char **attrs);
   39 
   40 void
   41 show_help (void)
   42 {
   43   puts ("\
   44 Usage: unattr [OPTION]... <FILE|DIRECTORY>...\n\
   45 Remove choosen xattr from files, recursively.\n\
   46 \n\
   47   -a, --attr        specify the name of a new attribute\n\
   48   -h, --help        help\n\
   49   -V, --version     show version number and copyright\n\
   50 Report bugs to <brice.arnould+shake@gmail.com> or at\n\
   51 https://github.com/unbrice/shake/issues\
   52 ");
   53 }
   54 
   55 /* If name refer to a regular file, call strip() on it.
   56  * If name refer to a directory, call itself on dir entries.
   57  * Else, or if open failed, do nothing.
   58  */
   59 void
   60 look (char *name, char **attr)
   61 {
   62   assert (name && attr);
   63   struct stat st;
   64   /* stat */
   65   if (-1 == lstat (name, &st))
   66     error (0, errno, "%s: stat() failed", name);
   67   else if (S_ISREG (st.st_mode))    // regular file
   68     strip (name, attr);
   69   else if (S_ISDIR (st.st_mode))    // directory
   70     {
   71       /* list it */
   72       char **flist = list_dir (name, false);
   73       if (!flist)
   74     {
   75       error (0, 0, "%s: list_dir() failed", name);
   76       return;
   77     }
   78       /* Go through the list */
   79       for (char **name = flist; *name; name++)
   80     {
   81       look (*name, attr);
   82       free (*name);
   83     }
   84       free (flist);
   85     }
   86 }
   87 
   88 void
   89 show_version (void)
   90 {
   91   puts ("\
   92 Unattr " VERSION "\n\
   93 Copyright (C) 2006-2008 Brice Arnould.\n\
   94 Unattr comes with ABSOLUTELY NO WARRANTY. You may redistribute copies of Unattr\n\
   95 under the terms of the GNU General Public License. For more information about\n\
   96 these matters, see the file named GPL.txt.\
   97 ");
   98 }
   99 
  100 /* This function remove attributes attr[0], attr[1]... attr[n]
  101  * with attr[n] == NULL, from the file named name
  102  */
  103 void
  104 strip (char *name, char **attr)
  105 {
  106   assert (name), assert (attr);
  107   int fd = open (name, O_WRONLY);
  108   if (0 > fd)
  109     {
  110       error (0, errno, "%s: open() failed", name);
  111       return;
  112     }
  113   for (char **attr = attr; *attr; attr++)
  114     attr_removef (fd, *attr, ATTR_DONTFOLLOW);
  115   close (fd);
  116 }
  117 
  118 int
  119 main (int argc, char **argv)
  120 {
  121   char **attr = NULL;
  122   /* Parse opts */
  123   {
  124     const uint BUFSTEP = 32;
  125     uint pos = 0;
  126     while (1)
  127       {
  128     int c;
  129     static const struct option long_options[] = {
  130       {"attr", required_argument, NULL, 'a'},
  131       {"help", no_argument, NULL, 'h'},
  132       {"version", no_argument, NULL, 'V'},
  133       {0, 0, 0, 0}
  134     };
  135     c = getopt_long (argc, argv, "a:hV", long_options, NULL);
  136     if (c == -1)
  137       break;
  138     switch (c)
  139       {
  140       case 'a':
  141         if (0 == pos % BUFSTEP)
  142           attr = realloc (attr, sizeof (*attr) * (pos + BUFSTEP + 1));
  143         if (!attr)
  144           error (1, errno, "alloc() failed");
  145         attr[pos] = strdup (optarg);
  146         if (!attr[pos++])
  147           error (1, errno, "alloc() failed");
  148         break;
  149       case 'h':
  150         show_help ();
  151         return 0;
  152       case 'V':
  153         show_version ();
  154         return 0;
  155       case 0:
  156       case '?':
  157       default:
  158         error (1, 0, "invalid args, aborting");
  159       }
  160       }
  161     if (!attr)
  162       return 0;
  163     attr[pos] = NULL;
  164   }
  165   /* For each name */
  166   if (attr)
  167     for (; optind < argc; optind++)
  168       look (argv[optind], attr);
  169   /* free */
  170   close_list (attr);
  171   return 0;
  172 }