2 * libdpkg - Debian packaging suite library routines
3 * db-ctrl-upgrade.c - package control information database format upgrade
5 * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 2011-2014 Guillem Jover <guillem@debian.org>
7 * Copyright © 2011 Linaro Limited
8 * Copyright © 2011 Raphaël Hertzog <hertzog@debian.org>
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.
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.
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/>.
27 #include <sys/types.h>
34 #include <dpkg/i18n.h>
35 #include <dpkg/dpkg.h>
36 #include <dpkg/dpkg-db.h>
37 #include <dpkg/fsys.h>
38 #include <dpkg/db-ctrl.h>
39 #include <dpkg/path.h>
43 struct rename_node
*next
;
48 /* Global variables. */
49 static struct rename_node
*rename_head
= NULL
;
51 static struct rename_node
*
52 rename_node_new(const char *old
, const char *new, struct rename_node
*next
)
54 struct rename_node
*node
;
56 node
= m_malloc(sizeof(*node
));
58 node
->old
= m_strdup(old
);
59 node
->new = m_strdup(new);
65 rename_node_free(struct rename_node
*node
)
73 pkg_infodb_link_multiarch_files(void)
77 struct varbuf pkgname
= VARBUF_INIT
;
78 struct varbuf oldname
= VARBUF_INIT
;
79 struct varbuf newname
= VARBUF_INIT
;
80 struct varbuf_state oldname_state
;
81 struct varbuf_state newname_state
;
83 varbuf_add_dir(&oldname
, pkg_infodb_get_dir());
84 varbuf_snapshot(&oldname
, &oldname_state
);
86 varbuf_set_varbuf(&newname
, &oldname
);
87 varbuf_snapshot(&newname
, &newname_state
);
89 db_dir
= opendir(pkg_infodb_get_dir());
91 ohshite(_("cannot read info directory"));
93 push_cleanup(cu_closedir
, ~0, 1, (void *)db_dir
);
94 while ((db_de
= readdir(db_dir
)) != NULL
) {
95 const char *filetype
, *dot
;
99 /* Ignore dotfiles, including ‘.’ and ‘..’. */
100 if (db_de
->d_name
[0] == '.')
103 /* Ignore anything odd. */
104 dot
= strrchr(db_de
->d_name
, '.');
108 varbuf_set_buf(&pkgname
, db_de
->d_name
, dot
- db_de
->d_name
);
110 /* Skip files already converted. */
111 if (strchr(pkgname
.buf
, ':'))
114 set
= pkg_hash_find_set(pkgname
.buf
);
115 for (pkg
= &set
->pkg
; pkg
; pkg
= pkg
->arch_next
)
116 if (pkg
->status
!= PKG_STAT_NOTINSTALLED
)
119 warning(_("info file %s/%s not associated to any package"),
120 pkg_infodb_get_dir(), db_de
->d_name
);
124 /* Does it need to be upgraded? */
125 if (pkg
->installed
.multiarch
!= PKG_MULTIARCH_SAME
)
128 /* Skip past the full stop. */
131 varbuf_rollback(&oldname_state
);
132 varbuf_add_str(&oldname
, db_de
->d_name
);
134 varbuf_rollback(&newname_state
);
135 varbuf_add_pkgbin_name(&newname
, pkg
, &pkg
->installed
, pnaw_always
);
136 varbuf_add_char(&newname
, '.');
137 varbuf_add_str(&newname
, filetype
);
139 if (link(oldname
.buf
, newname
.buf
) && errno
!= EEXIST
)
140 ohshite(_("error creating hard link '%.255s'"),
142 rename_head
= rename_node_new(oldname
.buf
, newname
.buf
, rename_head
);
144 pop_cleanup(ehflag_normaltidy
); /* closedir */
146 varbuf_destroy(&pkgname
);
147 varbuf_destroy(&newname
);
148 varbuf_destroy(&oldname
);
152 cu_abort_db_upgrade(int argc
, void **argv
)
154 struct atomic_file
*file
= argv
[0];
155 struct rename_node
*next
;
157 /* Restore the old files if needed and drop the newly created files. */
158 while (rename_head
) {
159 next
= rename_head
->next
;
160 if (link(rename_head
->new, rename_head
->old
) && errno
!= EEXIST
)
161 ohshite(_("error creating hard link '%.255s'"),
163 if (unlink(rename_head
->new))
164 ohshite(_("cannot remove '%.250s'"), rename_head
->new);
165 rename_node_free(rename_head
);
168 if (unlink(file
->name_new
) && errno
!= ENOENT
)
169 ohshite(_("cannot remove '%.250s'"), file
->name_new
);
171 atomic_file_free(file
);
175 pkg_infodb_write_format(struct atomic_file
*file
, int version
)
177 if (fprintf(file
->fp
, "%d\n", version
) < 0)
178 ohshite(_("error while writing '%s'"), file
->name_new
);
180 atomic_file_sync(file
);
181 atomic_file_close(file
);
182 dir_sync_path_parent(file
->name
);
184 pkg_infodb_set_format(version
);
188 pkg_infodb_unlink_monoarch_files(void)
190 struct rename_node
*next
;
192 while (rename_head
) {
193 next
= rename_head
->next
;
194 if (unlink(rename_head
->old
))
195 ohshite(_("cannot remove '%.250s'"), rename_head
->old
);
196 rename_node_free(rename_head
);
202 pkg_infodb_upgrade_to_multiarch(void)
204 struct atomic_file
*db_file
;
205 char *db_format_file
;
207 db_format_file
= dpkg_db_get_path(INFODIR
"/format");
208 db_file
= atomic_file_new(db_format_file
, ATOMIC_FILE_MKPATH
);
209 atomic_file_open(db_file
);
211 push_cleanup(cu_abort_db_upgrade
, ehflag_bombout
, 1, db_file
);
213 pkg_infodb_link_multiarch_files();
214 pkg_infodb_write_format(db_file
, 1);
216 pkg_infodb_unlink_monoarch_files();
217 atomic_file_commit(db_file
);
218 dir_sync_path(pkg_infodb_get_dir());
220 pop_cleanup(ehflag_normaltidy
);
222 atomic_file_free(db_file
);
223 free(db_format_file
);
227 * Upgrade the infodb if there's the need and possibility.
229 * Currently this implies, that the modstatdb was opened for writing and:
230 * - previous upgrade has not been completed; or
231 * - current format is not the latest one.
234 pkg_infodb_upgrade(void)
236 enum pkg_infodb_format db_format
;
238 /* Make sure to always read and verify the format version. */
239 db_format
= pkg_infodb_get_format();
241 if (modstatdb_get_status() < msdbrw_write
)
244 if (db_format
< PKG_INFODB_FORMAT_MULTIARCH
||
245 pkg_infodb_is_upgrading())
246 pkg_infodb_upgrade_to_multiarch();