2 * dpkg - main program for package management
3 * infodb-format.c - package control information database format
5 * Copyright © 2011-2014 Guillem Jover <guillem@debian.org>
7 * This is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 #include <sys/types.h>
31 #include <dpkg/i18n.h>
32 #include <dpkg/dpkg.h>
33 #include <dpkg/dpkg-db.h>
34 #include <dpkg/varbuf.h>
38 static enum pkg_infodb_format db_format = PKG_INFODB_FORMAT_UNKNOWN;
39 static bool db_upgrading;
41 static enum pkg_infodb_format
42 pkg_infodb_parse_format(const char *file)
47 fp = fopen(file, "r");
49 /* A missing format file means legacy format (0). */
51 return PKG_INFODB_FORMAT_LEGACY;
52 ohshite(_("error trying to open %.250s"), file);
55 if (fscanf(fp, "%u", &format) != 1)
56 ohshit(_("corrupt info database format file '%s'"), file);
63 static enum pkg_infodb_format
64 pkg_infodb_read_format(void)
66 struct atomic_file *file;
70 filename = dpkg_db_get_path(INFODIR "/format");
71 file = atomic_file_new(filename, 0);
73 db_format = pkg_infodb_parse_format(file->name);
75 /* Check if a previous upgrade got interrupted. Because we are only
76 * supposed to upgrade the db layout one format at a time, if the
77 * new file exists that means the new format is just one ahead,
78 * we don't try to read it because it contains unreliable data. */
79 if (stat(file->name_new, &st) == 0) {
84 atomic_file_free(file);
87 if (db_format < 0 || db_format >= PKG_INFODB_FORMAT_LAST)
88 ohshit(_("info database format (%d) is bogus or too new; "
89 "try getting a newer dpkg"), db_format);
94 enum pkg_infodb_format
95 pkg_infodb_get_format(void)
97 if (db_format > PKG_INFODB_FORMAT_UNKNOWN)
100 return pkg_infodb_read_format();
104 pkg_infodb_set_format(enum pkg_infodb_format version)
110 pkg_infodb_is_upgrading(void)
113 pkg_infodb_read_format();
119 pkg_infodb_get_dir(void)
121 static char *infodir;
124 infodir = dpkg_db_get_path(INFODIR);
130 pkg_infodb_get_file(struct pkginfo *pkg, struct pkgbin *pkgbin,
131 const char *filetype)
133 static struct varbuf vb;
134 enum pkg_infodb_format format;
136 /* Make sure to always read and verify the format version. */
137 format = pkg_infodb_get_format();
140 varbuf_add_str(&vb, pkg_infodb_get_dir());
141 varbuf_add_char(&vb, '/');
142 varbuf_add_str(&vb, pkg->set->name);
143 if (pkgbin->multiarch == PKG_MULTIARCH_SAME &&
144 format == PKG_INFODB_FORMAT_MULTIARCH)
145 varbuf_add_archqual(&vb, pkgbin->arch);
146 varbuf_add_char(&vb, '.');
147 varbuf_add_str(&vb, filetype);