Branch data Line data Source code
1 : : /*
2 : : * libdpkg - Debian packaging suite library routines
3 : : * db-ctrl-format.c - package control information database format
4 : : *
5 : : * Copyright © 2011-2014 Guillem Jover <guillem@debian.org>
6 : : *
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.
11 : : *
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.
16 : : *
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/>.
19 : : */
20 : :
21 : : #include <config.h>
22 : : #include <compat.h>
23 : :
24 : : #include <sys/types.h>
25 : : #include <sys/stat.h>
26 : :
27 : : #include <errno.h>
28 : : #include <stdlib.h>
29 : : #include <stdio.h>
30 : :
31 : : #include <dpkg/i18n.h>
32 : : #include <dpkg/dpkg.h>
33 : : #include <dpkg/dpkg-db.h>
34 : : #include <dpkg/varbuf.h>
35 : : #include <dpkg/db-ctrl.h>
36 : :
37 : : static enum pkg_infodb_format db_format = PKG_INFODB_FORMAT_UNKNOWN;
38 : : static bool db_upgrading;
39 : : static char *db_infodir;
40 : :
41 : : static enum pkg_infodb_format
42 : 1 : pkg_infodb_parse_format(const char *file)
43 : : {
44 : : FILE *fp;
45 : : unsigned int format;
46 : :
47 : 1 : fp = fopen(file, "r");
48 [ + - ]: 1 : if (fp == NULL) {
49 : : /* A missing format file means legacy format (0). */
50 [ + - ]: 1 : if (errno == ENOENT)
51 : 1 : return PKG_INFODB_FORMAT_LEGACY;
52 : 0 : ohshite(_("error trying to open %.250s"), file);
53 : : }
54 : :
55 [ # # ]: 0 : if (fscanf(fp, "%u", &format) != 1)
56 : 0 : ohshit(_("corrupt info database format file '%s'"), file);
57 : :
58 : 0 : fclose(fp);
59 : :
60 : 0 : return format;
61 : : }
62 : :
63 : : static enum pkg_infodb_format
64 : 1 : pkg_infodb_read_format(void)
65 : : {
66 : : struct atomic_file *file;
67 : : struct stat st;
68 : : char *filename;
69 : :
70 : 1 : filename = dpkg_db_get_path(INFODIR "/format");
71 : 1 : file = atomic_file_new(filename, 0);
72 : :
73 : 1 : db_format = pkg_infodb_parse_format(file->name);
74 : :
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 [ - + ]: 1 : if (stat(file->name_new, &st) == 0) {
80 : 0 : db_format++;
81 : 0 : db_upgrading = true;
82 : : }
83 : :
84 : 1 : atomic_file_free(file);
85 : 1 : free(filename);
86 : :
87 [ + - - + ]: 1 : if (db_format < 0 || db_format >= PKG_INFODB_FORMAT_LAST)
88 : 0 : ohshit(_("info database format (%d) is bogus or too new; "
89 : : "try getting a newer dpkg"), db_format);
90 : :
91 : 1 : return db_format;
92 : : }
93 : :
94 : : enum pkg_infodb_format
95 : 1 : pkg_infodb_get_format(void)
96 : : {
97 [ - + ]: 1 : if (db_format > PKG_INFODB_FORMAT_UNKNOWN)
98 : 0 : return db_format;
99 : : else
100 : 1 : return pkg_infodb_read_format();
101 : : }
102 : :
103 : : void
104 : 0 : pkg_infodb_set_format(enum pkg_infodb_format version)
105 : : {
106 : 0 : db_format = version;
107 : 0 : }
108 : :
109 : : bool
110 : 0 : pkg_infodb_is_upgrading(void)
111 : : {
112 [ # # ]: 0 : if (db_format < 0)
113 : 0 : pkg_infodb_read_format();
114 : :
115 : 0 : return db_upgrading;
116 : : }
117 : :
118 : : const char *
119 : 1 : pkg_infodb_get_dir(void)
120 : : {
121 [ + - ]: 1 : if (db_infodir == NULL)
122 : 1 : db_infodir = dpkg_db_get_path(INFODIR);
123 : :
124 : 1 : return db_infodir;
125 : : }
126 : :
127 : : const char *
128 : 1 : pkg_infodb_get_file(const struct pkginfo *pkg, const struct pkgbin *pkgbin,
129 : : const char *filetype)
130 : : {
131 : : static struct varbuf vb;
132 : : enum pkg_infodb_format format;
133 : :
134 : : /* Make sure to always read and verify the format version. */
135 : 1 : format = pkg_infodb_get_format();
136 : :
137 : 1 : varbuf_reset(&vb);
138 : 1 : varbuf_add_dir(&vb, pkg_infodb_get_dir());
139 : 1 : varbuf_add_str(&vb, pkg->set->name);
140 [ - + - - ]: 1 : if (pkgbin->multiarch == PKG_MULTIARCH_SAME &&
141 : : format == PKG_INFODB_FORMAT_MULTIARCH)
142 : 0 : varbuf_add_archqual(&vb, pkgbin->arch);
143 : 1 : varbuf_add_char(&vb, '.');
144 : 1 : varbuf_add_str(&vb, filetype);
145 : :
146 : 1 : return vb.buf;
147 : : }
148 : :
149 : : const char *
150 : 0 : pkg_infodb_reset_dir(void)
151 : : {
152 : 0 : free(db_infodir);
153 : 0 : db_infodir = NULL;
154 : :
155 : 0 : return pkg_infodb_get_dir();
156 : : }
|