Cleaned up command line arguments handling in chsmack.
authorJarkko Sakkinen <jarkko.sakkinen@intel.com>
Mon, 17 Jun 2013 21:59:01 +0000 (00:59 +0300)
committerJarkko Sakkinen <jarkko.sakkinen@intel.com>
Tue, 18 Jun 2013 06:14:50 +0000 (09:14 +0300)
Argument handling code looks terrible at the moment in chsmack.
Migrated to getopt_long().

doc/chsmack.8
utils/chsmack.c

index 21e5867..af70482 100644 (file)
@@ -23,7 +23,7 @@
 .SH NAME
 chsmack \- Change the Smack properties of a filesystem object
 .SH SYNOPSIS 
-.B chsmack [\-a|\-\-access=] [-e|--exec=|--execute=] [-m|--mmap=]
+.B chsmack [\-a|\-\-access=] [-e|--exec=] [-m|--mmap=]
 .I <context>
 .B [-t|--transmute]
 .SH DESCRIPTION
index 7a2b504..10fc0d9 100644 (file)
@@ -19,6 +19,7 @@
  *
  * Author:
  *      Casey Schaufler <casey@schaufler-ca.com>
+ *      Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
  */
 
 #include <sys/types.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <getopt.h>
 
-
-static inline int leads(char *in, char *lead)
+int main(int argc, char *argv[])
 {
-       return (strncmp(in, lead, strlen(lead)) == 0);
-}
+       static struct option long_options[] = {
+               {"access", required_argument, 0, 'a'},
+               {"exec", required_argument, 0, 'e'},
+               {"mmap", required_argument, 0, 'm'},
+               {"transmute", no_argument, 0, 't'},
+               {0, 0, 0, 0}
+       };
 
-int
-main(int argc, char *argv[])
-{
+       /*  Buffers are zeroed automatically by keeping them static variables.
+        *  No separate memset is needed this way.
+        */
+       static char access_buf[SMACK_LABEL_LEN + 1];
+       static char exec_buf[SMACK_LABEL_LEN + 1];
+       static char mmap_buf[SMACK_LABEL_LEN + 1];
+
+       int transmute_flag = 0;
+       int option_flag = 0;
+       int option_index;
        int rc;
-       int argi;
-       int transmute = 0;
-       char buffer[SMACK_LABEL_LEN + 1];
-       char *access = NULL;
-       char *mm = NULL;
-       char *execute = NULL;
-
-       for (argi = 1; argi < argc; argi++) {
-               if (strcmp(argv[argi], "-a") == 0)
-                       access = argv[++argi];
-               else if (leads(argv[argi], "--access="))
-                       access = argv[argi] + strlen("--access=");
-               else if (strcmp(argv[argi], "-e") == 0)
-                       execute = argv[++argi];
-               else if (leads(argv[argi], "--exec="))
-                       execute = argv[argi] + strlen("--exec=");
-               else if (leads(argv[argi], "--execute="))
-                       execute = argv[argi] + strlen("--execute=");
-               else if (strcmp(argv[argi], "-m") == 0)
-                       mm = argv[++argi];
-               else if (leads(argv[argi], "--mmap="))
-                       mm = argv[argi] + strlen("--mmap=");
-               else if (strcmp(argv[argi], "-t") == 0)
-                       transmute = 1;
-               else if (strcmp(argv[argi], "--transmute") == 0)
-                       transmute = 1;
-               else if (*argv[argi] == '-') {
-                       fprintf(stderr, "Invalid argument \"%s\".\n",
-                               argv[argi]);
-                       exit(1);
+       int c;
+       int i;
+
+       while ((c = getopt_long(argc, argv, "a:e:m:t", long_options,
+                               &option_index)) != -1) {
+               if ((c == 'a' || c == 'e' || c == 'm')
+                   && strnlen(optarg, SMACK_LABEL_LEN + 1)
+                      == (SMACK_LABEL_LEN + 1)) {
+                       fprintf(stderr, "%s label \"%s\" "
+                                       "exceeds %d characters.\n",
+                               long_options[option_index].name, optarg,
+                               SMACK_LABEL_LEN);
                }
-               /*
-                * Indicates the start of filenames.
-                */
-               else
-                       break;
-       }
-       if (argi >= argc) {
-               fprintf(stderr, "No files specified.\n");
-               exit(1);
-       }
-       if (access != NULL && strlen(access) > SMACK_LABEL_LEN) {
-               fprintf(stderr, "Access label \"%s\" exceeds %d characters.\n",
-                       access, SMACK_LABEL_LEN);
-               exit(1);
-       }
-       if (mm != NULL && strlen(mm) > SMACK_LABEL_LEN) {
-               fprintf(stderr, "mmap label \"%s\" exceeds %d characters.\n",
-                       mm, SMACK_LABEL_LEN);
-               exit(1);
-       }
-       if (execute != NULL && strlen(execute) > SMACK_LABEL_LEN) {
-               fprintf(stderr, "execute label \"%s\" exceeds %d characters.\n",
-                       execute, SMACK_LABEL_LEN);
-               exit(1);
+
+               switch (c) {
+                       case 'a':
+                               strncpy(access_buf, optarg, SMACK_LABEL_LEN + 1);
+                               break;
+                       case 'e':
+                               strncpy(exec_buf, optarg, SMACK_LABEL_LEN + 1);
+                               break;
+                       case 'm':
+                               strncpy(mmap_buf, optarg, SMACK_LABEL_LEN + 1);
+                               break;
+                       case 't':
+                               transmute_flag = 1;
+                               break;
+                       default:
+                               printf("Usage: %s [options] <path>\n", argv[0]);
+                               printf("options:\n");
+                               printf(" [--access|-a] set security.SMACK64\n");
+                               printf(" [--exec|-e] set security.SMACK64EXEC\n");
+                               printf(" [--mmap|-m] set security.SMACK64MMAP\n");
+                               printf(" [--transmute|-t] set security.SMACK64TRANSMUTE\n");
+                               exit(1);
+               }
+
+               option_flag = 1;
        }
-       for (; argi < argc; argi++) {
-               if (access == NULL && mm == NULL &&
-                   execute == NULL && !transmute) {
-                       printf("%s", argv[argi]);
-                       rc = lgetxattr(argv[argi], "security.SMACK64",
-                               buffer, SMACK_LABEL_LEN + 1);
+
+       for (i = optind; i < argc; i++) {
+               if (option_flag) {
+                       if (strlen(access_buf) > 0) {
+                               rc = lsetxattr(argv[i], "security.SMACK64",
+                                              access_buf, strlen(access_buf) + 1, 0);
+                               if (rc < 0)
+                                       perror(argv[i]);
+                       }
+
+                       if (strlen(exec_buf) > 0) {
+                               rc = lsetxattr(argv[i], "security.SMACK64EXEC",
+                                              exec_buf, strlen(exec_buf) + 1, 0);
+                               if (rc < 0)
+                                       perror(argv[i]);
+                       }
+
+                       if (strlen(mmap_buf) > 0) {
+                               rc = lsetxattr(argv[i], "security.SMACK64MMAP",
+                                              mmap_buf, strlen(mmap_buf) + 1, 0);
+                               if (rc < 0)
+                                       perror(argv[i]);
+                       }
+
+                       if (transmute_flag) {
+                               rc = lsetxattr(argv[i], "security.SMACK64TRANSMUTE",
+                                              "TRUE", 4, 0);
+                               if (rc < 0)
+                                       perror(argv[i]);
+                       }
+               } else {
+                       /* Print file path. */
+                       printf("%s", argv[i]);
+
+                       rc = lgetxattr(argv[i], "security.SMACK64", access_buf,
+                                      SMACK_LABEL_LEN + 1);
                        if (rc > 0) {
-                               buffer[rc] = '\0';
-                               printf(" access=\"%s\"", buffer);
+                               access_buf[rc] = '\0';
+                               printf(" access=\"%s\"", access_buf);
                        }
-                       rc = lgetxattr(argv[argi], "security.SMACK64EXEC",
-                               buffer, SMACK_LABEL_LEN + 1);
+
+                       rc = lgetxattr(argv[i], "security.SMACK64EXEC", access_buf,
+                                      SMACK_LABEL_LEN + 1);
                        if (rc > 0) {
-                               buffer[rc] = '\0';
-                               printf(" execute=\"%s\"", buffer);
+                               access_buf[rc] = '\0';
+                               printf(" execute=\"%s\"", access_buf);
+
                        }
-                       rc = lgetxattr(argv[argi], "security.SMACK64MMAP",
-                               buffer, SMACK_LABEL_LEN + 1);
+                       rc = lgetxattr(argv[i], "security.SMACK64MMAP", access_buf,
+                                      SMACK_LABEL_LEN + 1);
                        if (rc > 0) {
-                               buffer[rc] = '\0';
-                               printf(" mmap=\"%s\"", buffer);
+                               access_buf[rc] = '\0';
+                               printf(" mmap=\"%s\"", access_buf);
                        }
-                       rc = lgetxattr(argv[argi], "security.SMACK64TRANSMUTE",
-                               buffer, SMACK_LABEL_LEN + 1);
+
+                       rc = lgetxattr(argv[i], "security.SMACK64TRANSMUTE",
+                                      access_buf, SMACK_LABEL_LEN + 1);
                        if (rc > 0) {
-                               buffer[rc] = '\0';
-                               printf(" transmute=\"%s\"", buffer);
+                               access_buf[rc] = '\0';
+                               printf(" transmute=\"%s\"", access_buf);
                        }
+
                        printf("\n");
-                       continue;
-               }
-               if (access != NULL) {
-                       rc = lsetxattr(argv[argi], "security.SMACK64",
-                               access, strlen(access) + 1, 0);
-                       if (rc < 0)
-                               perror(argv[argi]);
-               }
-               if (execute != NULL) {
-                       rc = lsetxattr(argv[argi], "security.SMACK64EXEC",
-                               execute, strlen(execute) + 1, 0);
-                       if (rc < 0)
-                               perror(argv[argi]);
-               }
-               if (mm != NULL) {
-                       rc = lsetxattr(argv[argi], "security.SMACK64MMAP",
-                               mm, strlen(mm) + 1, 0);
-                       if (rc < 0)
-                               perror(argv[argi]);
-               }
-               if (transmute) {
-                       rc = lsetxattr(argv[argi], "security.SMACK64TRANSMUTE",
-                               "TRUE", 4, 0);
-                       if (rc < 0)
-                               perror(argv[argi]);
                }
        }
+
        exit(0);
 }