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 <sysexits.h>
38 : #include <ctype.h>
39 :
40 : #include "pkgcli.h"
41 :
42 : void
43 0 : usage_shlib(void)
44 : {
45 0 : fprintf(stderr, "Usage: pkg shlib [-q] [-P|R] <library>\n\n");
46 0 : fprintf(stderr, "<library> should be a filename without leading path.\n");
47 0 : fprintf(stderr, "For more information see 'pkg help shlib'.\n");
48 0 : }
49 :
50 : char*
51 0 : sanitize(char *target, const char *source, size_t size)
52 : {
53 : size_t i;
54 : int s;
55 0 : char *rc = target;
56 :
57 0 : for (i = 0; i < size - 1; i++) {
58 0 : s = source[i];
59 0 : if (s == '\0')
60 0 : break;
61 0 : if (isascii(s) && (isspace(s) || s == '/')) {
62 0 : rc = NULL;
63 0 : break;
64 : } else {
65 0 : target[i] = s;
66 : }
67 : }
68 0 : target[i] = '\0';
69 :
70 0 : return (rc);
71 : }
72 :
73 : static int
74 0 : pkgs_providing_lib(struct pkgdb *db, const char *libname)
75 : {
76 0 : struct pkgdb_it *it = NULL;
77 0 : struct pkg *pkg = NULL;
78 0 : int ret = EPKG_OK;
79 0 : int count = 0;
80 :
81 0 : if ((it = pkgdb_query_shlib_provide(db, libname)) == NULL) {
82 0 : return (EPKG_FATAL);
83 : }
84 :
85 0 : while ((ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) {
86 0 : if (count == 0 && !quiet)
87 0 : printf("%s is provided by the following packages:\n",
88 : libname);
89 0 : count++;
90 0 : pkg_printf("%n-%v\n", pkg, pkg);
91 : }
92 :
93 0 : if (ret == EPKG_END) {
94 0 : if (count == 0 && !quiet)
95 0 : printf("No packages provide %s.\n", libname);
96 0 : ret = EPKG_OK;
97 : }
98 :
99 0 : pkg_free(pkg);
100 0 : pkgdb_it_free(it);
101 :
102 0 : return (ret);
103 : }
104 :
105 : static int
106 0 : pkgs_requiring_lib(struct pkgdb *db, const char *libname)
107 : {
108 0 : struct pkgdb_it *it = NULL;
109 0 : struct pkg *pkg = NULL;
110 0 : int ret = EPKG_OK;
111 0 : int count = 0;
112 :
113 0 : if ((it = pkgdb_query_shlib_require(db, libname)) == NULL) {
114 0 : return (EPKG_FATAL);
115 : }
116 :
117 0 : while ((ret = pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC)) == EPKG_OK) {
118 0 : if (count == 0 && !quiet)
119 0 : printf("%s is linked to by the following packages:\n",
120 : libname);
121 0 : count++;
122 0 : pkg_printf("%n-%v\n", pkg, pkg);
123 : }
124 :
125 0 : if (ret == EPKG_END) {
126 0 : if (count == 0 && !quiet)
127 0 : printf("No packages require %s.\n", libname);
128 0 : ret = EPKG_OK;
129 : }
130 :
131 0 : pkg_free(pkg);
132 0 : pkgdb_it_free(it);
133 :
134 0 : return (ret);
135 : }
136 :
137 : int
138 0 : exec_shlib(int argc, char **argv)
139 : {
140 0 : struct pkgdb *db = NULL;
141 : char libname[MAXPATHLEN];
142 0 : int retcode = EPKG_OK;
143 : int ch;
144 0 : bool provides_only = false;
145 0 : bool requires_only = false;
146 :
147 0 : struct option longopts[] = {
148 : { "provides", no_argument, NULL, 'P' },
149 : { "requires", no_argument, NULL, 'R' },
150 : { "quiet" , no_argument, NULL, 'q' },
151 : { NULL, 0, NULL, 0 },
152 : };
153 :
154 0 : while ((ch = getopt_long(argc, argv, "+qPR", longopts, NULL)) != -1) {
155 0 : switch (ch) {
156 : case 'P':
157 0 : provides_only = true;
158 0 : break;
159 : case 'R':
160 0 : requires_only = true;
161 0 : break;
162 : case 'q':
163 0 : quiet = true;
164 0 : break;
165 : default:
166 0 : usage_shlib();
167 0 : return (EX_USAGE);
168 : }
169 : }
170 0 : argc -= optind;
171 0 : argv += optind;
172 :
173 0 : if (argc < 1 || (provides_only && requires_only)) {
174 0 : usage_shlib();
175 0 : return (EX_USAGE);
176 : }
177 :
178 0 : if (argc >= 2) {
179 0 : warnx("multiple libraries per run not allowed");
180 0 : return (EX_USAGE);
181 : }
182 :
183 0 : if (sanitize(libname, argv[0], sizeof(libname)) == NULL) {
184 0 : usage_shlib();
185 0 : return (EX_USAGE);
186 : }
187 :
188 0 : retcode = pkgdb_open(&db, PKGDB_DEFAULT);
189 0 : if (retcode != EPKG_OK)
190 0 : return (EX_IOERR);
191 :
192 0 : if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) {
193 0 : pkgdb_close(db);
194 0 : warnx("Cannot get a read lock on a database, it is locked by another process");
195 0 : return (EX_TEMPFAIL);
196 : }
197 :
198 0 : if (retcode == EPKG_OK && !requires_only)
199 0 : retcode = pkgs_providing_lib(db, libname);
200 :
201 0 : if (retcode == EPKG_OK && !provides_only)
202 0 : retcode = pkgs_requiring_lib(db, libname);
203 :
204 0 : if (retcode != EPKG_OK)
205 0 : retcode = (EX_IOERR);
206 :
207 0 : pkgdb_release_lock(db, PKGDB_LOCK_READONLY);
208 0 : pkgdb_close(db);
209 0 : return (retcode);
210 : }
|