1*2d543d20SAndroid Build Coastguard Worker /* Authors: Karl MacMillan <[email protected]>
2*2d543d20SAndroid Build Coastguard Worker *
3*2d543d20SAndroid Build Coastguard Worker * Copyright (C) 2004 Tresys Technology, LLC
4*2d543d20SAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or modify
5*2d543d20SAndroid Build Coastguard Worker * it under the terms of the GNU General Public License as published by
6*2d543d20SAndroid Build Coastguard Worker * the Free Software Foundation, version 2.
7*2d543d20SAndroid Build Coastguard Worker */
8*2d543d20SAndroid Build Coastguard Worker
9*2d543d20SAndroid Build Coastguard Worker #include <sepol/module.h>
10*2d543d20SAndroid Build Coastguard Worker
11*2d543d20SAndroid Build Coastguard Worker #include <getopt.h>
12*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
13*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
14*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
15*2d543d20SAndroid Build Coastguard Worker #include <sys/mman.h>
16*2d543d20SAndroid Build Coastguard Worker #include <sys/types.h>
17*2d543d20SAndroid Build Coastguard Worker #include <sys/stat.h>
18*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
19*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
20*2d543d20SAndroid Build Coastguard Worker #include <string.h>
21*2d543d20SAndroid Build Coastguard Worker
22*2d543d20SAndroid Build Coastguard Worker #define LINKPOLICY_VERSION "1.0"
23*2d543d20SAndroid Build Coastguard Worker
usage(const char * program_name)24*2d543d20SAndroid Build Coastguard Worker static void usage(const char *program_name)
25*2d543d20SAndroid Build Coastguard Worker {
26*2d543d20SAndroid Build Coastguard Worker printf("usage: %s [-hVv] [-o outfile] basemodpkg modpkg1 [modpkg2]...\n",
27*2d543d20SAndroid Build Coastguard Worker program_name);
28*2d543d20SAndroid Build Coastguard Worker }
29*2d543d20SAndroid Build Coastguard Worker
load_module(const char * filename,const char * progname)30*2d543d20SAndroid Build Coastguard Worker static sepol_module_package_t *load_module(const char *filename, const char *progname)
31*2d543d20SAndroid Build Coastguard Worker {
32*2d543d20SAndroid Build Coastguard Worker int ret;
33*2d543d20SAndroid Build Coastguard Worker FILE *fp = NULL;
34*2d543d20SAndroid Build Coastguard Worker struct sepol_policy_file *pf = NULL;
35*2d543d20SAndroid Build Coastguard Worker sepol_module_package_t *p = NULL;
36*2d543d20SAndroid Build Coastguard Worker
37*2d543d20SAndroid Build Coastguard Worker if (sepol_module_package_create(&p)) {
38*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "%s: Out of memory\n", progname);
39*2d543d20SAndroid Build Coastguard Worker goto bad;
40*2d543d20SAndroid Build Coastguard Worker }
41*2d543d20SAndroid Build Coastguard Worker if (sepol_policy_file_create(&pf)) {
42*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "%s: Out of memory\n", progname);
43*2d543d20SAndroid Build Coastguard Worker goto bad;
44*2d543d20SAndroid Build Coastguard Worker }
45*2d543d20SAndroid Build Coastguard Worker fp = fopen(filename, "re");
46*2d543d20SAndroid Build Coastguard Worker if (!fp) {
47*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "%s: Could not open package %s: %s\n", progname,
48*2d543d20SAndroid Build Coastguard Worker filename, strerror(errno));
49*2d543d20SAndroid Build Coastguard Worker goto bad;
50*2d543d20SAndroid Build Coastguard Worker }
51*2d543d20SAndroid Build Coastguard Worker sepol_policy_file_set_fp(pf, fp);
52*2d543d20SAndroid Build Coastguard Worker
53*2d543d20SAndroid Build Coastguard Worker printf("%s: loading package from file %s\n", progname, filename);
54*2d543d20SAndroid Build Coastguard Worker
55*2d543d20SAndroid Build Coastguard Worker ret = sepol_module_package_read(p, pf, 0);
56*2d543d20SAndroid Build Coastguard Worker if (ret) {
57*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "%s: Error while reading package from %s\n",
58*2d543d20SAndroid Build Coastguard Worker progname, filename);
59*2d543d20SAndroid Build Coastguard Worker goto bad;
60*2d543d20SAndroid Build Coastguard Worker }
61*2d543d20SAndroid Build Coastguard Worker fclose(fp);
62*2d543d20SAndroid Build Coastguard Worker sepol_policy_file_free(pf);
63*2d543d20SAndroid Build Coastguard Worker return p;
64*2d543d20SAndroid Build Coastguard Worker bad:
65*2d543d20SAndroid Build Coastguard Worker sepol_module_package_free(p);
66*2d543d20SAndroid Build Coastguard Worker sepol_policy_file_free(pf);
67*2d543d20SAndroid Build Coastguard Worker if (fp)
68*2d543d20SAndroid Build Coastguard Worker fclose(fp);
69*2d543d20SAndroid Build Coastguard Worker return NULL;
70*2d543d20SAndroid Build Coastguard Worker }
71*2d543d20SAndroid Build Coastguard Worker
main(int argc,char ** argv)72*2d543d20SAndroid Build Coastguard Worker int main(int argc, char **argv)
73*2d543d20SAndroid Build Coastguard Worker {
74*2d543d20SAndroid Build Coastguard Worker int ch, i, ret, show_version = 0, verbose = 0, num_mods = 0;
75*2d543d20SAndroid Build Coastguard Worker const char *basename, *outname = NULL;
76*2d543d20SAndroid Build Coastguard Worker sepol_module_package_t *base = NULL, **mods = NULL;
77*2d543d20SAndroid Build Coastguard Worker struct sepol_policy_file *pf = NULL;
78*2d543d20SAndroid Build Coastguard Worker
79*2d543d20SAndroid Build Coastguard Worker while ((ch = getopt(argc, argv, "ho:Vv")) != EOF) {
80*2d543d20SAndroid Build Coastguard Worker switch (ch) {
81*2d543d20SAndroid Build Coastguard Worker case 'h':
82*2d543d20SAndroid Build Coastguard Worker usage(argv[0]);
83*2d543d20SAndroid Build Coastguard Worker return EXIT_SUCCESS;
84*2d543d20SAndroid Build Coastguard Worker case 'V':
85*2d543d20SAndroid Build Coastguard Worker show_version = 1;
86*2d543d20SAndroid Build Coastguard Worker break;
87*2d543d20SAndroid Build Coastguard Worker case 'v':
88*2d543d20SAndroid Build Coastguard Worker verbose = 1;
89*2d543d20SAndroid Build Coastguard Worker break;
90*2d543d20SAndroid Build Coastguard Worker case 'o':
91*2d543d20SAndroid Build Coastguard Worker outname = optarg;
92*2d543d20SAndroid Build Coastguard Worker break;
93*2d543d20SAndroid Build Coastguard Worker default:
94*2d543d20SAndroid Build Coastguard Worker usage(argv[0]);
95*2d543d20SAndroid Build Coastguard Worker return EXIT_FAILURE;
96*2d543d20SAndroid Build Coastguard Worker }
97*2d543d20SAndroid Build Coastguard Worker }
98*2d543d20SAndroid Build Coastguard Worker
99*2d543d20SAndroid Build Coastguard Worker if (show_version) {
100*2d543d20SAndroid Build Coastguard Worker printf("%s\n", LINKPOLICY_VERSION);
101*2d543d20SAndroid Build Coastguard Worker return EXIT_SUCCESS;
102*2d543d20SAndroid Build Coastguard Worker }
103*2d543d20SAndroid Build Coastguard Worker
104*2d543d20SAndroid Build Coastguard Worker /* check args */
105*2d543d20SAndroid Build Coastguard Worker if (argc < 3 || optind + 2 > argc) {
106*2d543d20SAndroid Build Coastguard Worker fprintf(stderr,
107*2d543d20SAndroid Build Coastguard Worker "%s: You must provide the base module package and at least one other module package\n",
108*2d543d20SAndroid Build Coastguard Worker argv[0]);
109*2d543d20SAndroid Build Coastguard Worker usage(argv[0]);
110*2d543d20SAndroid Build Coastguard Worker return EXIT_FAILURE;
111*2d543d20SAndroid Build Coastguard Worker }
112*2d543d20SAndroid Build Coastguard Worker
113*2d543d20SAndroid Build Coastguard Worker basename = argv[optind++];
114*2d543d20SAndroid Build Coastguard Worker base = load_module(basename, argv[0]);
115*2d543d20SAndroid Build Coastguard Worker if (!base) {
116*2d543d20SAndroid Build Coastguard Worker fprintf(stderr,
117*2d543d20SAndroid Build Coastguard Worker "%s: Could not load base module from file %s\n",
118*2d543d20SAndroid Build Coastguard Worker argv[0], basename);
119*2d543d20SAndroid Build Coastguard Worker goto failure;
120*2d543d20SAndroid Build Coastguard Worker }
121*2d543d20SAndroid Build Coastguard Worker
122*2d543d20SAndroid Build Coastguard Worker num_mods = argc - optind;
123*2d543d20SAndroid Build Coastguard Worker mods = calloc(num_mods, sizeof(sepol_module_package_t *));
124*2d543d20SAndroid Build Coastguard Worker if (!mods) {
125*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "%s: Out of memory\n", argv[0]);
126*2d543d20SAndroid Build Coastguard Worker goto failure;
127*2d543d20SAndroid Build Coastguard Worker }
128*2d543d20SAndroid Build Coastguard Worker
129*2d543d20SAndroid Build Coastguard Worker for (i = 0; optind < argc; optind++, i++) {
130*2d543d20SAndroid Build Coastguard Worker mods[i] = load_module(argv[optind], argv[0]);
131*2d543d20SAndroid Build Coastguard Worker if (!mods[i]) {
132*2d543d20SAndroid Build Coastguard Worker fprintf(stderr,
133*2d543d20SAndroid Build Coastguard Worker "%s: Could not load module from file %s\n",
134*2d543d20SAndroid Build Coastguard Worker argv[0], argv[optind]);
135*2d543d20SAndroid Build Coastguard Worker goto failure;
136*2d543d20SAndroid Build Coastguard Worker }
137*2d543d20SAndroid Build Coastguard Worker }
138*2d543d20SAndroid Build Coastguard Worker
139*2d543d20SAndroid Build Coastguard Worker if (sepol_link_packages(NULL, base, mods, num_mods, verbose)) {
140*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "%s: Error while linking packages\n", argv[0]);
141*2d543d20SAndroid Build Coastguard Worker goto failure;
142*2d543d20SAndroid Build Coastguard Worker }
143*2d543d20SAndroid Build Coastguard Worker
144*2d543d20SAndroid Build Coastguard Worker if (outname) {
145*2d543d20SAndroid Build Coastguard Worker FILE *outfile = fopen(outname, "we");
146*2d543d20SAndroid Build Coastguard Worker if (!outfile) {
147*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "%s: Could not open output file %s: %s\n",
148*2d543d20SAndroid Build Coastguard Worker argv[0], outname, strerror(errno));
149*2d543d20SAndroid Build Coastguard Worker goto failure;
150*2d543d20SAndroid Build Coastguard Worker }
151*2d543d20SAndroid Build Coastguard Worker
152*2d543d20SAndroid Build Coastguard Worker if (sepol_policy_file_create(&pf)) {
153*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "%s: Out of memory\n", argv[0]);
154*2d543d20SAndroid Build Coastguard Worker fclose(outfile);
155*2d543d20SAndroid Build Coastguard Worker goto failure;
156*2d543d20SAndroid Build Coastguard Worker }
157*2d543d20SAndroid Build Coastguard Worker sepol_policy_file_set_fp(pf, outfile);
158*2d543d20SAndroid Build Coastguard Worker if (sepol_module_package_write(base, pf)) {
159*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "%s: Error writing linked package.\n",
160*2d543d20SAndroid Build Coastguard Worker argv[0]);
161*2d543d20SAndroid Build Coastguard Worker sepol_policy_file_free(pf);
162*2d543d20SAndroid Build Coastguard Worker fclose(outfile);
163*2d543d20SAndroid Build Coastguard Worker goto failure;
164*2d543d20SAndroid Build Coastguard Worker }
165*2d543d20SAndroid Build Coastguard Worker sepol_policy_file_free(pf);
166*2d543d20SAndroid Build Coastguard Worker
167*2d543d20SAndroid Build Coastguard Worker if (fclose(outfile)) {
168*2d543d20SAndroid Build Coastguard Worker fprintf(stderr, "%s: Error closing linked package: %s\n",
169*2d543d20SAndroid Build Coastguard Worker argv[0], strerror(errno));
170*2d543d20SAndroid Build Coastguard Worker goto failure;
171*2d543d20SAndroid Build Coastguard Worker }
172*2d543d20SAndroid Build Coastguard Worker }
173*2d543d20SAndroid Build Coastguard Worker
174*2d543d20SAndroid Build Coastguard Worker ret = EXIT_SUCCESS;
175*2d543d20SAndroid Build Coastguard Worker goto cleanup;
176*2d543d20SAndroid Build Coastguard Worker
177*2d543d20SAndroid Build Coastguard Worker failure:
178*2d543d20SAndroid Build Coastguard Worker ret = EXIT_FAILURE;
179*2d543d20SAndroid Build Coastguard Worker
180*2d543d20SAndroid Build Coastguard Worker cleanup:
181*2d543d20SAndroid Build Coastguard Worker if (mods) {
182*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < num_mods; i++)
183*2d543d20SAndroid Build Coastguard Worker sepol_module_package_free(mods[i]);
184*2d543d20SAndroid Build Coastguard Worker free(mods);
185*2d543d20SAndroid Build Coastguard Worker }
186*2d543d20SAndroid Build Coastguard Worker sepol_module_package_free(base);
187*2d543d20SAndroid Build Coastguard Worker
188*2d543d20SAndroid Build Coastguard Worker return ret;
189*2d543d20SAndroid Build Coastguard Worker }
190