2 * dpkg-deb - construction and deconstruction of *.deb archives
3 * info.c - providing information
5 * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 2001 Wichert Akkerman
7 * Copyright © 2007-2015 Guillem Jover <guillem@debian.org>
9 * This is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
26 #include <sys/types.h>
40 #include <dpkg/i18n.h>
41 #include <dpkg/c-ctype.h>
42 #include <dpkg/dpkg.h>
43 #include <dpkg/dpkg-db.h>
44 #include <dpkg/parsedump.h>
45 #include <dpkg/pkg-format.h>
46 #include <dpkg/buffer.h>
47 #include <dpkg/path.h>
48 #include <dpkg/options.h>
52 static void cu_info_prepare(int argc, void **argv) {
56 path_remove_tree(dir);
60 static void info_prepare(const char *const **argvp,
67 if (!*debarp) badusage(_("--%s needs a .deb filename argument"),cipaction->olong);
69 dbuf = mkdtemp(path_make_temp_template("dpkg-deb"));
71 ohshite(_("unable to create temporary directory"));
74 push_cleanup(cu_info_prepare, -1, NULL, 0, 1, (void *)dbuf);
75 extracthalf(*debarp, dbuf, DPKG_TAR_EXTRACT | DPKG_TAR_NOMTIME, admininfo);
78 static int ilist_select(const struct dirent *de) {
79 return strcmp(de->d_name,".") && strcmp(de->d_name,"..");
83 info_spew(const char *debar, const char *dir, const char *const *argv)
85 struct dpkg_error err;
86 const char *component;
87 struct varbuf controlfile = VARBUF_INIT;
91 while ((component = *argv++) != NULL) {
92 varbuf_reset(&controlfile);
93 varbuf_printf(&controlfile, "%s/%s", dir, component);
95 fd = open(controlfile.buf, O_RDONLY);
97 if (fd_fd_copy(fd, 1, -1, &err) < 0)
98 ohshit(_("cannot extract control file '%s' from '%s': %s"),
99 controlfile.buf, debar, err.str);
101 } else if (errno == ENOENT) {
102 notice(_("'%.255s' contains no control component '%.255s'"),
106 ohshite(_("open component '%.255s' (in %.255s) failed in an unexpected way"),
110 varbuf_destroy(&controlfile);
113 ohshit(P_("%d requested control component is missing",
114 "%d requested control components are missing", re), re);
118 info_list(const char *debar, const char *dir)
120 char interpreter[INTERPRETER_MAX+1], *p;
122 struct varbuf controlfile = VARBUF_INIT;
123 struct dirent **cdlist, *cdep;
129 cdn = scandir(dir, &cdlist, &ilist_select, alphasort);
131 ohshite(_("cannot scan directory '%.255s'"), dir);
133 for (n = 0; n < cdn; n++) {
136 varbuf_reset(&controlfile);
137 varbuf_printf(&controlfile, "%s/%s", dir, cdep->d_name);
139 if (stat(controlfile.buf, &stab))
140 ohshite(_("cannot stat '%.255s' (in '%.255s')"), cdep->d_name, dir);
141 if (S_ISREG(stab.st_mode)) {
142 cc = fopen(controlfile.buf, "r");
144 ohshite(_("cannot open '%.255s' (in '%.255s')"), cdep->d_name, dir);
146 interpreter[0] = '\0';
147 if (getc(cc) == '#') {
148 if (getc(cc) == '!') {
149 while ((c= getc(cc))== ' ');
150 p=interpreter; *p++='#'; *p++='!'; il=2;
151 while (il < INTERPRETER_MAX && !c_isspace(c) && c != EOF) {
152 *p++= c; il++; c= getc(cc);
155 if (c=='\n') lines++;
158 while ((c= getc(cc))!= EOF) { if (c == '\n') lines++; }
160 ohshite(_("failed to read '%.255s' (in '%.255s')"), cdep->d_name, dir);
162 printf(_(" %7jd bytes, %5d lines %c %-20.127s %.127s\n"),
163 (intmax_t)stab.st_size, lines, S_IXUSR & stab.st_mode ? '*' : ' ',
164 cdep->d_name, interpreter);
166 printf(_(" not a plain file %.255s\n"), cdep->d_name);
172 varbuf_reset(&controlfile);
173 varbuf_printf(&controlfile, "%s/%s", dir, CONTROLFILE);
174 cc = fopen(controlfile.buf, "r");
177 ohshite(_("failed to read '%.255s' (in '%.255s')"), CONTROLFILE, dir);
178 warning(_("no 'control' file in control archive!"));
181 while ((c= getc(cc))!= EOF) {
191 ohshite(_("failed to read '%.255s' (in '%.255s')"), CONTROLFILE, dir);
195 m_output(stdout, _("<standard output>"));
196 varbuf_destroy(&controlfile);
200 info_field(const char *debar, const char *dir, const char *const *fields,
201 enum fwriteflags fieldflags)
204 struct varbuf str = VARBUF_INIT;
208 controlfile = str_fmt("%s/%s", dir, CONTROLFILE);
209 parsedb(controlfile, pdb_parse_binary | pdb_ignorefiles, &pkg);
212 for (i = 0; fields[i]; i++) {
213 const struct fieldinfo *field;
214 const struct arbitraryfield *arbfield;
217 field = find_field_info(fieldinfos, fields[i]);
219 field->wcall(&str, pkg, &pkg->available, fieldflags, field);
221 arbfield = find_arbfield_info(pkg->available.arbs, fields[i]);
223 varbuf_add_arbfield(&str, arbfield, fieldflags);
225 varbuf_end_str(&str);
227 if (fieldflags & fw_printheader)
228 printf("%s", str.buf);
230 printf("%s\n", str.buf);
233 m_output(stdout, _("<standard output>"));
235 varbuf_destroy(&str);
239 do_showinfo(const char *const *argv)
241 const char *debar, *dir;
243 struct dpkg_error err;
245 struct pkg_format_node *fmt;
247 fmt = pkg_format_parse(showformat, &err);
249 ohshit(_("error in show format: %s"), err.str);
251 info_prepare(&argv, &debar, &dir, 1);
253 controlfile = str_fmt("%s/%s", dir, CONTROLFILE);
254 parsedb(controlfile, pdb_parse_binary | pdb_ignorefiles, &pkg);
255 pkg_format_show(fmt, pkg, &pkg->available);
256 pkg_format_free(fmt);
263 do_info(const char *const *argv)
265 const char *debar, *dir;
267 if (*argv && argv[1]) {
268 info_prepare(&argv, &debar, &dir, 1);
269 info_spew(debar, dir, argv);
271 info_prepare(&argv, &debar, &dir, 2);
272 info_list(debar, dir);
279 do_field(const char *const *argv)
281 const char *debar, *dir;
283 info_prepare(&argv, &debar, &dir, 1);
285 info_field(debar, dir, argv, argv[1] != NULL ? fw_printheader : 0);
287 static const char *const controlonly[] = { CONTROLFILE, NULL };
288 info_spew(debar, dir, controlonly);
295 do_contents(const char *const *argv)
297 const char *debar = *argv++;
299 if (debar == NULL || *argv)
300 badusage(_("--%s takes exactly one argument"), cipaction->olong);
301 extracthalf(debar, NULL, DPKG_TAR_LIST, 0);