123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- /*
- * libdpkg - Debian packaging suite library routines
- * showpkg.c - customizable package listing
- *
- * Copyright © 2001 Wichert Akkerman <wakkerma@debian.org>
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * This is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <config.h>
- #include <compat.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <dpkg/i18n.h>
- #include <dpkg/dpkg.h>
- #include <dpkg/dpkg-db.h>
- #include <dpkg/parsedump.h>
- typedef enum {
- invalid,
- string,
- field,
- } itemtype_t;
- struct lstitem {
- itemtype_t type;
- size_t width;
- int pad;
- char *data;
- struct lstitem *next;
- };
- static struct lstitem *
- alloclstitem(void)
- {
- struct lstitem *buf;
- buf = m_malloc(sizeof(struct lstitem));
- buf->type = invalid;
- buf->next = NULL;
- buf->data = NULL;
- buf->width = 0;
- buf->pad = 0;
- return buf;
- }
- static int
- parsefield(struct lstitem *cur, const char *fmt, const char *fmtend)
- {
- int len;
- const char *ws;
- len = fmtend - fmt + 1;
- ws = memchr(fmt, ';', len);
- if (ws) {
- char *endptr;
- long w;
- w = strtol(ws + 1, &endptr, 0);
- if (endptr[0] != '}') {
- fprintf(stderr,
- _("invalid character `%c' in field width\n"),
- *endptr);
- return 0;
- }
- if (w < 0) {
- cur->pad = 1;
- cur->width = (size_t)-w;
- } else
- cur->width = (size_t)w;
- len = ws - fmt;
- }
- cur->type = field;
- cur->data = m_malloc(len + 1);
- memcpy(cur->data, fmt, len);
- cur->data[len] = '\0';
- return 1;
- }
- static int
- parsestring(struct lstitem *cur, const char *fmt, const char *fmtend)
- {
- int len;
- char *write;
- len = fmtend - fmt + 1;
- cur->type = string;
- write = cur->data = m_malloc(len + 1);
- while (fmt <= fmtend) {
- if (*fmt == '\\') {
- fmt++;
- switch (*fmt) {
- case 'n':
- *write = '\n';
- break;
- case 't':
- *write = '\t';
- break;
- case 'r':
- *write = '\r';
- break;
- case '\\':
- default:
- *write = *fmt;
- break;
- }
- } else
- *write = *fmt;
- write++;
- fmt++;
- }
- *write = '\0';
- return 1;
- }
- void
- freeformat(struct lstitem *head)
- {
- struct lstitem *next;
- while (head) {
- next = head->next;
- free(head->data);
- free(head);
- head = next;
- }
- }
- struct lstitem *
- parseformat(const char *fmt)
- {
- struct lstitem *head;
- struct lstitem *cur;
- const char *fmtend;
- head = cur = NULL;
- while (*fmt) {
- if (cur)
- cur = cur->next = alloclstitem();
- else
- head = cur = alloclstitem();
- if (fmt[0] == '$' && fmt[1] == '{') {
- fmtend = strchr(fmt, '}');
- if (!fmtend) {
- fprintf(stderr,
- _("Closing brace missing in format\n"));
- freeformat(head);
- return NULL;
- }
- if (!parsefield(cur, fmt + 2, fmtend - 1)) {
- freeformat(head);
- return NULL;
- }
- fmt = fmtend + 1;
- } else {
- fmtend = fmt;
- do {
- fmtend += 1;
- fmtend = strchr(fmtend, '$');
- } while (fmtend && fmtend[1] != '{');
- if (!fmtend)
- fmtend = fmt + strlen(fmt);
- if (!parsestring(cur, fmt, fmtend - 1)) {
- freeformat(head);
- return NULL;
- }
- fmt = fmtend;
- }
- }
- return head;
- }
- void
- show1package(const struct lstitem *head, struct pkginfo *pkg)
- {
- struct varbuf vb = VARBUF_INIT, fb = VARBUF_INIT, wb = VARBUF_INIT;
- /* Make sure we have package info available, even if it's all empty. */
- if (!pkg->installed.valid)
- blankpackageperfile(&pkg->installed);
- while (head) {
- int ok;
- char fmt[16];
- ok = 0;
- if (head->width > 0)
- snprintf(fmt, 16, "%%%s%zds",
- ((head->pad) ? "-" : ""), head->width);
- else
- strcpy(fmt, "%s");
- if (head->type == string) {
- varbufprintf(&fb, fmt, head->data);
- ok = 1;
- } else if (head->type == field) {
- const struct fieldinfo *fip;
- for (fip = fieldinfos; fip->name; fip++)
- if (strcasecmp(head->data, fip->name) == 0) {
- fip->wcall(&wb, pkg, &pkg->installed, 0, fip);
- varbufaddc(&wb, '\0');
- varbufprintf(&fb, fmt, wb.buf);
- varbufreset(&wb);
- ok = 1;
- break;
- }
- if (!fip->name && pkg->installed.valid) {
- const struct arbitraryfield *afp;
- for (afp = pkg->installed.arbs; afp; afp = afp->next)
- if (strcasecmp(head->data, afp->name) == 0) {
- varbufprintf(&fb, fmt, afp->value);
- ok = 1;
- break;
- }
- }
- }
- if (ok) {
- size_t len = strlen(fb.buf);
- if ((head->width > 0) && (len > head->width))
- len = head->width;
- varbufaddbuf(&vb, fb.buf, len);
- }
- varbufreset(&fb);
- head = head->next;
- }
- if (vb.buf) {
- varbufaddc(&vb, '\0');
- fputs(vb.buf, stdout);
- }
- varbuffree(&wb);
- varbuffree(&fb);
- varbuffree(&vb);
- }
|