Branch data Line data Source code
1 : : /*-
2 : : * Copyright (c) 2012-2014 Matthew Seaman <matthew@FreeBSD.org>
3 : : * All rights reserved.
4 : : *
5 : : * Redistribution and use in source and binary forms, with or without
6 : : * modification, are permitted provided that the following conditions
7 : : * are met:
8 : : * 1. Redistributions of source code must retain the above copyright
9 : : * notice, this list of conditions and the following disclaimer
10 : : * in this position and unchanged.
11 : : * 2. Redistributions in binary form must reproduce the above copyright
12 : : * notice, this list of conditions and the following disclaimer in the
13 : : * documentation and/or other materials provided with the distribution.
14 : : *
15 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 : : * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 : : */
26 : :
27 : : #include <sys/param.h>
28 : :
29 : : #include <err.h>
30 : : #include <getopt.h>
31 : : #include <stdio.h>
32 : : #include <pkg.h>
33 : : #include <libgen.h>
34 : : #include <stdlib.h>
35 : : #include <string.h>
36 : : #include <unistd.h>
37 : : #include <ctype.h>
38 : :
39 : : #include "pkgcli.h"
40 : :
41 : : void
42 : 0 : usage_shlib(void)
43 : : {
44 : 0 : fprintf(stderr, "Usage: pkg shlib [-q] [-P|R] <library>\n\n");
45 : 0 : fprintf(stderr, "<library> should be a filename without leading path.\n");
46 : 0 : fprintf(stderr, "For more information see 'pkg help shlib'.\n");
47 : 0 : }
48 : :
49 : : char*
50 : 0 : sanitize(char *target, const char *source, size_t size)
51 : : {
52 : : size_t i;
53 : : int s;
54 : 0 : char *rc = target;
55 : :
56 [ # # ]: 0 : for (i = 0; i < size - 1; i++) {
57 : 0 : s = source[i];
58 [ # # ]: 0 : if (s == '\0')
59 : 0 : break;
60 [ # # # # : 0 : if (isascii(s) && (isspace(s) || s == '/')) {
# # ]
61 : 0 : rc = NULL;
62 : 0 : break;
63 : : } else {
64 : 0 : target[i] = s;
65 : : }
66 : 0 : }
67 : 0 : target[i] = '\0';
68 : :
69 : 0 : return (rc);
70 : : }
71 : :
72 : : static int
73 : 0 : pkgs_providing_lib(struct pkgdb *db, const char *libname)
74 : : {
75 : 0 : struct pkgdb_it *it = NULL;
76 : 0 : struct pkg *pkg = NULL;
77 : 0 : int ret = EPKG_OK;
78 : 0 : int count = 0;
79 : :
80 [ # # ]: 0 : if ((it = pkgdb_query_shlib_provide(db, libname)) == NULL) {
81 : 0 : return (EPKG_FATAL);
82 : : }
83 : :
84 [ # # ]: 0 : while ((ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) {
85 [ # # # # ]: 0 : if (count == 0 && !quiet)
86 : 0 : printf("%s is provided by the following packages:\n",
87 : 0 : libname);
88 : 0 : count++;
89 : 0 : pkg_printf("%n-%v\n", pkg, pkg);
90 : : }
91 : :
92 [ # # ]: 0 : if (ret == EPKG_END) {
93 [ # # # # ]: 0 : if (count == 0 && !quiet)
94 : 0 : printf("No packages provide %s.\n", libname);
95 : 0 : ret = EPKG_OK;
96 : 0 : }
97 : :
98 : 0 : pkg_free(pkg);
99 : 0 : pkgdb_it_free(it);
100 : :
101 : 0 : return (ret);
102 : 0 : }
103 : :
104 : : static int
105 : 0 : pkgs_requiring_lib(struct pkgdb *db, const char *libname)
106 : : {
107 : 0 : struct pkgdb_it *it = NULL;
108 : 0 : struct pkg *pkg = NULL;
109 : 0 : int ret = EPKG_OK;
110 : 0 : int count = 0;
111 : :
112 [ # # ]: 0 : if ((it = pkgdb_query_shlib_require(db, libname)) == NULL) {
113 : 0 : return (EPKG_FATAL);
114 : : }
115 : :
116 [ # # ]: 0 : while ((ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) {
117 [ # # # # ]: 0 : if (count == 0 && !quiet)
118 : 0 : printf("%s is linked to by the following packages:\n",
119 : 0 : libname);
120 : 0 : count++;
121 : 0 : pkg_printf("%n-%v\n", pkg, pkg);
122 : : }
123 : :
124 [ # # ]: 0 : if (ret == EPKG_END) {
125 [ # # # # ]: 0 : if (count == 0 && !quiet)
126 : 0 : printf("No packages require %s.\n", libname);
127 : 0 : ret = EPKG_OK;
128 : 0 : }
129 : :
130 : 0 : pkg_free(pkg);
131 : 0 : pkgdb_it_free(it);
132 : :
133 : 0 : return (ret);
134 : 0 : }
135 : :
136 : : int
137 : 0 : exec_shlib(int argc, char **argv)
138 : : {
139 : 0 : struct pkgdb *db = NULL;
140 : : char libname[MAXPATHLEN];
141 : 0 : int retcode = EPKG_OK;
142 : : int ch;
143 : 0 : bool provides_only = false;
144 : 0 : bool requires_only = false;
145 : :
146 : 0 : struct option longopts[] = {
147 : : { "provides", no_argument, NULL, 'P' },
148 : : { "requires", no_argument, NULL, 'R' },
149 : : { "quiet" , no_argument, NULL, 'q' },
150 : : { NULL, 0, NULL, 0 },
151 : : };
152 : :
153 [ # # ]: 0 : while ((ch = getopt_long(argc, argv, "+qPR", longopts, NULL)) != -1) {
154 [ # # # # ]: 0 : switch (ch) {
155 : : case 'P':
156 : 0 : provides_only = true;
157 : 0 : break;
158 : : case 'R':
159 : 0 : requires_only = true;
160 : 0 : break;
161 : : case 'q':
162 : 0 : quiet = true;
163 : 0 : break;
164 : : default:
165 : 0 : usage_shlib();
166 : 0 : return (EXIT_FAILURE);
167 : : }
168 : : }
169 : 0 : argc -= optind;
170 : 0 : argv += optind;
171 : :
172 [ # # # # : 0 : if (argc < 1 || (provides_only && requires_only)) {
# # ]
173 : 0 : usage_shlib();
174 : 0 : return (EXIT_FAILURE);
175 : : }
176 : :
177 [ # # ]: 0 : if (argc >= 2) {
178 : 0 : warnx("multiple libraries per run not allowed");
179 : 0 : return (EXIT_FAILURE);
180 : : }
181 : :
182 [ # # ]: 0 : if (sanitize(libname, argv[0], sizeof(libname)) == NULL) {
183 : 0 : usage_shlib();
184 : 0 : return (EXIT_FAILURE);
185 : : }
186 : :
187 : 0 : retcode = pkgdb_open(&db, PKGDB_DEFAULT);
188 [ # # ]: 0 : if (retcode != EPKG_OK)
189 : 0 : return (EXIT_FAILURE);
190 : :
191 [ # # ]: 0 : if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) {
192 : 0 : pkgdb_close(db);
193 : 0 : warnx("Cannot get a read lock on a database, it is locked by another process");
194 : 0 : return (EXIT_FAILURE);
195 : : }
196 : :
197 [ # # # # ]: 0 : if (retcode == EPKG_OK && !requires_only)
198 : 0 : retcode = pkgs_providing_lib(db, libname);
199 : :
200 [ # # # # ]: 0 : if (retcode == EPKG_OK && !provides_only)
201 : 0 : retcode = pkgs_requiring_lib(db, libname);
202 : :
203 [ # # ]: 0 : if (retcode != EPKG_OK)
204 : 0 : retcode = (EXIT_FAILURE);
205 : :
206 : 0 : pkgdb_release_lock(db, PKGDB_LOCK_READONLY);
207 : 0 : pkgdb_close(db);
208 : 0 : return (retcode);
209 : 0 : }
|