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 : 1 : varbuf_end_str(&vb); 146 : : 147 : 1 : return vb.buf; 148 : : } 149 : : 150 : : const char * 151 : 0 : pkg_infodb_reset_dir(void) 152 : : { 153 : 0 : free(db_infodir); 154 : 0 : db_infodir = NULL; 155 : : 156 : 0 : return pkg_infodb_get_dir(); 157 : : }