1 /*
2  * dpkg - main program for package management
3  * select.c - by-hand (rather than dselect-based) package selection
4  *
5  * Copyright © 1995,1996 Ian Jackson <ijackson@chiark.greenend.org.uk>
6  * Copyright © 2006, 2008-2015 Guillem Jover <guillem@debian.org>
7  * Copyright © 2011 Linaro Limited
8  * Copyright © 2011 Raphaël Hertzog <hertzog@debian.org>
9  *
10  * This is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
22  */
23 
24 #include <config.h>
25 #include <compat.h>
26 
27 #include <fnmatch.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 
32 #include <dpkg/i18n.h>
33 #include <dpkg/c-ctype.h>
34 #include <dpkg/dpkg.h>
35 #include <dpkg/dpkg-db.h>
36 #include <dpkg/pkg-array.h>
37 #include <dpkg/pkg-show.h>
38 #include <dpkg/pkg-spec.h>
39 #include <dpkg/options.h>
40 #include <dpkg/db-ctrl.h>
41 #include <dpkg/db-fsys.h>
42 
43 #include "main.h"
44 
getsel1package(struct pkginfo * pkg)45 static void getsel1package(struct pkginfo *pkg) {
46   const char *pkgname;
47   int l;
48 
49   if (pkg->want == PKG_WANT_UNKNOWN)
50     return;
51   pkgname = pkg_name(pkg, pnaw_nonambig);
52   l = strlen(pkgname);
53   l >>= 3;
54   l = 6 - l;
55   if (l < 1)
56     l = 1;
57   printf("%s%.*s%s\n", pkgname, l, "\t\t\t\t\t\t", pkg_want_name(pkg));
58 }
59 
60 int
getselections(const char * const * argv)61 getselections(const char *const *argv)
62 {
63   struct pkg_array array;
64   struct pkginfo *pkg;
65   const char *thisarg;
66   int i, found;
67 
68   modstatdb_open(msdbrw_readonly);
69 
70   pkg_array_init_from_hash(&array);
71   pkg_array_sort(&array, pkg_sorter_by_nonambig_name_arch);
72 
73   if (!*argv) {
74     for (i = 0; i < array.n_pkgs; i++) {
75       pkg = array.pkgs[i];
76       if (pkg->status == PKG_STAT_NOTINSTALLED)
77         continue;
78       getsel1package(pkg);
79     }
80   } else {
81     while ((thisarg= *argv++)) {
82       struct pkg_spec pkgspec;
83 
84       found= 0;
85       pkg_spec_init(&pkgspec, PKG_SPEC_PATTERNS | PKG_SPEC_ARCH_WILDCARD);
86       pkg_spec_parse(&pkgspec, thisarg);
87 
88       for (i = 0; i < array.n_pkgs; i++) {
89         pkg = array.pkgs[i];
90         if (!pkg_spec_match_pkg(&pkgspec, pkg, &pkg->installed))
91           continue;
92         getsel1package(pkg); found++;
93       }
94       if (!found)
95         notice(_("no packages found matching %s"), thisarg);
96 
97       pkg_spec_destroy(&pkgspec);
98     }
99   }
100 
101   m_output(stdout, _("<standard output>"));
102   m_output(stderr, _("<standard error>"));
103 
104   pkg_array_destroy(&array);
105 
106   modstatdb_shutdown();
107 
108   return 0;
109 }
110 
111 int
setselections(const char * const * argv)112 setselections(const char *const *argv)
113 {
114   enum modstatdb_rw msdbflags;
115   const struct namevalue *nv;
116   struct pkginfo *pkg;
117   int c, lno;
118   struct varbuf namevb = VARBUF_INIT;
119   struct varbuf selvb = VARBUF_INIT;
120   bool db_possibly_outdated = false;
121 
122   if (*argv)
123     badusage(_("--%s takes no arguments"), cipaction->olong);
124 
125   msdbflags = msdbrw_available_readonly;
126   if (f_noact)
127     msdbflags |= msdbrw_readonly;
128   else
129     msdbflags |= msdbrw_write;
130 
131   modstatdb_open(msdbflags);
132   pkg_infodb_upgrade();
133 
134   lno= 1;
135   for (;;) {
136     struct dpkg_error err;
137 
138     do {
139       c = getchar();
140       if (c == '\n')
141         lno++;
142     } while (c != EOF && c_isspace(c));
143     if (c == EOF) break;
144     if (c == '#') {
145       do { c= getchar(); if (c == '\n') lno++; } while (c != EOF && c != '\n');
146       continue;
147     }
148 
149     varbuf_reset(&namevb);
150     while (!c_isspace(c)) {
151       varbuf_add_char(&namevb, c);
152       c= getchar();
153       if (c == EOF)
154         ohshit(_("unexpected end of file in package name at line %d"), lno);
155       if (c == '\n') ohshit(_("unexpected end of line in package name at line %d"),lno);
156     }
157     varbuf_end_str(&namevb);
158 
159     while (c != EOF && c_isspace(c)) {
160       c= getchar();
161       if (c == EOF)
162         ohshit(_("unexpected end of file after package name at line %d"), lno);
163       if (c == '\n') ohshit(_("unexpected end of line after package name at line %d"),lno);
164     }
165 
166     varbuf_reset(&selvb);
167     while (c != EOF && !c_isspace(c)) {
168       varbuf_add_char(&selvb, c);
169       c= getchar();
170     }
171     varbuf_end_str(&selvb);
172 
173     while (c != EOF && c != '\n') {
174       c= getchar();
175       if (!c_isspace(c))
176         ohshit(_("unexpected data after package and selection at line %d"),lno);
177     }
178     pkg = pkg_spec_parse_pkg(namevb.buf, &err);
179     if (pkg == NULL)
180       ohshit(_("illegal package name at line %d: %.250s"), lno, err.str);
181 
182     if (!pkg_is_informative(pkg, &pkg->installed) &&
183         !pkg_is_informative(pkg, &pkg->available)) {
184       db_possibly_outdated = true;
185       warning(_("package not in status nor available database at line %d: %.250s"), lno, namevb.buf);
186       lno++;
187       continue;
188     }
189 
190     nv = namevalue_find_by_name(wantinfos, selvb.buf);
191     if (nv == NULL)
192       ohshit(_("unknown wanted status at line %d: %.250s"), lno, selvb.buf);
193 
194     pkg_set_want(pkg, nv->value);
195     if (c == EOF) break;
196     lno++;
197   }
198   if (ferror(stdin)) ohshite(_("read error on standard input"));
199   modstatdb_shutdown();
200   varbuf_destroy(&namevb);
201   varbuf_destroy(&selvb);
202 
203   if (db_possibly_outdated)
204     warning(_("found unknown packages; this might mean the available database\n"
205               "is outdated, and needs to be updated through a frontend method;\n"
206               "please see the FAQ <https://wiki.debian.org/Teams/Dpkg/FAQ>"));
207 
208   return 0;
209 }
210 
211 int
clearselections(const char * const * argv)212 clearselections(const char *const *argv)
213 {
214   enum modstatdb_rw msdbflags;
215   struct pkg_hash_iter *iter;
216   struct pkginfo *pkg;
217 
218   if (*argv)
219     badusage(_("--%s takes no arguments"), cipaction->olong);
220 
221   if (f_noact)
222     msdbflags = msdbrw_readonly;
223   else
224     msdbflags = msdbrw_write;
225 
226   modstatdb_open(msdbflags);
227   pkg_infodb_upgrade();
228 
229   iter = pkg_hash_iter_new();
230   while ((pkg = pkg_hash_iter_next_pkg(iter))) {
231     if (!pkg->installed.essential)
232       pkg_set_want(pkg, PKG_WANT_DEINSTALL);
233   }
234   pkg_hash_iter_free(iter);
235 
236   modstatdb_shutdown();
237 
238   return 0;
239 }
240 
241