Branch data Line data Source code
1 : : /*
2 : : * libdpkg - Debian packaging suite library routines
3 : : * db-fsys-digest.c - management of filesystem digests database
4 : : *
5 : : * Copyright © 2012-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/stat.h>
25 : :
26 : : #include <errno.h>
27 : : #include <string.h>
28 : : #include <stdio.h>
29 : : #include <fcntl.h>
30 : : #include <unistd.h>
31 : :
32 : : #include <dpkg/i18n.h>
33 : : #include <dpkg/dpkg.h>
34 : : #include <dpkg/dpkg-db.h>
35 : : #include <dpkg/debug.h>
36 : : #include <dpkg/fdio.h>
37 : : #include <dpkg/dir.h>
38 : : #include <dpkg/db-ctrl.h>
39 : : #include <dpkg/db-fsys.h>
40 : :
41 : : /*
42 : : * If mask is nonzero, will not write any file whose fsys_namenode
43 : : * has any flag bits set in mask.
44 : : */
45 : : void
46 : 0 : write_filehash_except(struct pkginfo *pkg, struct pkgbin *pkgbin,
47 : : struct fsys_namenode_list *list, enum fsys_namenode_flags mask)
48 : : {
49 : : struct atomic_file *file;
50 : : const char *hashfile;
51 : :
52 : 0 : debug(dbg_general, "generating infodb hashfile");
53 : :
54 [ # # ]: 0 : if (pkg_infodb_has_file(pkg, &pkg->available, HASHFILE))
55 : 0 : return;
56 : :
57 : 0 : hashfile = pkg_infodb_get_file(pkg, pkgbin, HASHFILE);
58 : :
59 : 0 : file = atomic_file_new(hashfile, 0);
60 : 0 : atomic_file_open(file);
61 : :
62 [ # # ]: 0 : for (; list; list = list->next) {
63 : 0 : const struct fsys_namenode *namenode = list->namenode;
64 : :
65 [ # # # # ]: 0 : if (mask && (namenode->flags & mask))
66 : 0 : continue;
67 [ # # ]: 0 : if (namenode->newhash == NULL)
68 : 0 : continue;
69 : :
70 : 0 : fprintf(file->fp, "%s %s\n",
71 : 0 : namenode->newhash, namenode->name + 1);
72 : : }
73 : :
74 : 0 : atomic_file_sync(file);
75 : 0 : atomic_file_close(file);
76 : 0 : atomic_file_commit(file);
77 : 0 : atomic_file_free(file);
78 : :
79 : 0 : dir_sync_path(pkg_infodb_get_dir());
80 : : }
81 : :
82 : : static void
83 : 0 : parse_filehash_buffer(struct varbuf *buf,
84 : : struct pkginfo *pkg, struct pkgbin *pkgbin)
85 : : {
86 : : char *thisline, *nextline;
87 : 0 : const char *pkgname = pkg_name(pkg, pnaw_nonambig);
88 : 0 : const char *buf_end = buf->buf + buf->used;
89 : :
90 [ # # ]: 0 : for (thisline = buf->buf; thisline < buf_end; thisline = nextline) {
91 : : struct fsys_namenode *namenode;
92 : : char *endline, *hash_end, *filename;
93 : :
94 : 0 : endline = memchr(thisline, '\n', buf_end - thisline);
95 [ # # ]: 0 : if (endline == NULL)
96 : 0 : ohshit(_("control file '%s' for package '%s' is "
97 : : "missing final newline"), HASHFILE, pkgname);
98 : :
99 : : /* The md5sum hash has a constant length. */
100 : 0 : hash_end = thisline + MD5HASHLEN;
101 : :
102 : 0 : filename = hash_end + 2;
103 [ # # ]: 0 : if (filename + 1 > endline)
104 : 0 : ohshit(_("control file '%s' for package '%s' is "
105 : : "missing value"), HASHFILE, pkgname);
106 : :
107 [ # # # # ]: 0 : if (hash_end[0] != ' ' || hash_end[1] != ' ')
108 : 0 : ohshit(_("control file '%s' for package '%s' is "
109 : : "missing value separator"), HASHFILE, pkgname);
110 : 0 : hash_end[0] = '\0';
111 : :
112 : : /* Where to start next time around. */
113 : 0 : nextline = endline + 1;
114 : :
115 : : /* Strip trailing ‘/’. */
116 [ # # # # ]: 0 : if (endline > thisline && endline[-1] == '/')
117 : 0 : endline--;
118 : 0 : *endline = '\0';
119 : :
120 [ # # ]: 0 : if (endline == thisline)
121 : 0 : ohshit(_("control file '%s' for package '%s' "
122 : : "contains empty filename"), HASHFILE, pkgname);
123 : :
124 : 0 : debug(dbg_eachfiledetail, "load digest '%s' for filename '%s'",
125 : : thisline, filename);
126 : :
127 : : /* Add the file to the list. */
128 : 0 : namenode = fsys_hash_find_node(filename, FHFF_NONE);
129 : 0 : namenode->newhash = nfstrsave(thisline);
130 : : }
131 : 0 : }
132 : :
133 : : void
134 : 0 : parse_filehash(struct pkginfo *pkg, struct pkgbin *pkgbin)
135 : : {
136 : : const char *hashfile;
137 : 0 : struct varbuf buf = VARBUF_INIT;
138 : 0 : struct dpkg_error err = DPKG_ERROR_INIT;
139 : :
140 : 0 : hashfile = pkg_infodb_get_file(pkg, pkgbin, HASHFILE);
141 : :
142 [ # # # # ]: 0 : if (file_slurp(hashfile, &buf, &err) < 0 && err.syserrno != ENOENT)
143 : 0 : dpkg_error_print(&err,
144 : 0 : _("loading control file '%s' for package '%s'"),
145 : : HASHFILE, pkg_name(pkg, pnaw_nonambig));
146 : :
147 [ # # ]: 0 : if (buf.used > 0)
148 : 0 : parse_filehash_buffer(&buf, pkg, pkgbin);
149 : :
150 : 0 : varbuf_destroy(&buf);
151 : 0 : }
|