Extend make_ext4fs to support setting SELinux security contexts in ext4 images.

Extend make_ext4fs with support for looking up the right security context from
the file_contexts configuration and setting it in the generated image.  This is
similar to the existing support for looking up the UID/GID/mode via
android_filesystem_config.h and setting it, but via configuration rather than
defined in a header.

Change-Id: Ief9c44eeaaca4a44100a384b063f40b185469be3
diff --git a/ext4_utils/make_ext4fs_main.c b/ext4_utils/make_ext4fs_main.c
index d616c6d..6a885d2 100644
--- a/ext4_utils/make_ext4fs_main.c
+++ b/ext4_utils/make_ext4fs_main.c
@@ -33,6 +33,7 @@
         fprintf(stderr, "%s [ -l <len> ] [ -j <journal size> ] [ -b <block_size> ]\n", basename(path));
         fprintf(stderr, "    [ -g <blocks per group> ] [ -i <inodes> ] [ -I <inode size> ]\n");
         fprintf(stderr, "    [ -L <label> ] [ -f ] [ -a <android mountpoint> ]\n");
+        fprintf(stderr, "    [ -S file_contexts ]\n");
         fprintf(stderr, "    [ -z | -s ] [ -t ] [ -w ] [ -c ] [ -J ]\n");
         fprintf(stderr, "    <filename> [<directory>]\n");
 }
@@ -49,8 +50,12 @@
         int crc = 0;
         int wipe = 0;
         int init_itabs = 0;
+        struct selabel_handle *sehnd = NULL;
+#ifdef HAVE_SELINUX
+        struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "" } };
+#endif
 
-        while ((opt = getopt(argc, argv, "l:j:b:g:i:I:L:a:fwzJsct")) != -1) {
+        while ((opt = getopt(argc, argv, "l:j:b:g:i:I:L:a:fwzJsctS:")) != -1) {
                 switch (opt) {
                 case 'l':
                         info.len = parse_num(optarg);
@@ -98,6 +103,16 @@
                 case 't':
                         init_itabs = 1;
                         break;
+                case 'S':
+#ifdef HAVE_SELINUX
+                        seopts[0].value = optarg;
+                        sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1);
+                        if (!sehnd) {
+                            perror(optarg);
+                            exit(EXIT_FAILURE);
+                        }
+#endif
+                        break;
                 default: /* '?' */
                         usage(argv[0]);
                         exit(EXIT_FAILURE);
@@ -140,5 +155,5 @@
         }
 
         return make_ext4fs_internal(filename, directory, mountpoint, android, gzip,
-                       sparse, crc, wipe, init_itabs);
+                       sparse, crc, wipe, init_itabs, sehnd);
 }