1 /* $NetBSD: specspec.c,v 1.2 2012/10/05 01:27:29 christos Exp $ */
4 * Copyright (c) 2003 Poul-Henning Kamp
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #if HAVE_NBTOOL_CONFIG_H
30 #include "nbtool_config.h"
33 #include <sys/cdefs.h>
34 __RCSID("$NetBSD: specspec.c,v 1.2 2012/10/05 01:27:29 christos Exp $");
48 #define FF(a, b, c, d) \
49 (((a)->flags & (c)) && ((b)->flags & (c)) && ((a)->d) != ((b)->d))
50 #define FS(a, b, c, d) \
51 (((a)->flags & (c)) && ((b)->flags & (c)) && strcmp((a)->d,(b)->d))
52 #define FM(a, b, c, d) \
53 (((a)->flags & (c)) && ((b)->flags & (c)) && memcmp(&(a)->d,&(b)->d, sizeof (a)->d))
56 shownode(NODE
*n
, int f
, char const *path
)
61 printf("%s%s %s", path
, n
->name
, inotype(nodetoino(n
->type
)));
63 printf(" cksum=%lu", n
->cksum
);
65 printf(" gid=%d", n
->st_gid
);
67 gr
= getgrgid(n
->st_gid
);
69 printf(" gid=%d", n
->st_gid
);
71 printf(" gname=%s", gr
->gr_name
);
74 printf(" mode=%o", n
->st_mode
);
76 printf(" nlink=%d", n
->st_nlink
);
78 printf(" size=%jd", (intmax_t)n
->st_size
);
80 printf(" uid=%d", n
->st_uid
);
82 pw
= getpwuid(n
->st_uid
);
84 printf(" uid=%d", n
->st_uid
);
86 printf(" uname=%s", pw
->pw_name
);
89 printf(" %s=%s", MD5KEY
, n
->md5digest
);
91 printf(" %s=%s", SHA1KEY
, n
->sha1digest
);
93 printf(" %s=%s", RMD160KEY
, n
->rmd160digest
);
95 printf(" %s=%s", SHA256KEY
, n
->sha256digest
);
97 printf(" %s=%s", SHA384KEY
, n
->sha384digest
);
99 printf(" %s=%s", SHA512KEY
, n
->sha512digest
);
101 printf(" flags=%s", flags_to_string(n
->st_flags
, "none"));
106 mismatch(NODE
*n1
, NODE
*n2
, int differ
, char const *path
)
110 shownode(n1
, differ
, path
);
115 shownode(n2
, differ
, path
);
118 if (!(differ
& keys
))
121 shownode(n1
, differ
, path
);
123 shownode(n2
, differ
, path
);
128 compare_nodes(NODE
*n1
, NODE
*n2
, char const *path
)
132 if (n1
!= NULL
&& n1
->type
== F_LINK
)
133 n1
->flags
&= ~F_MODE
;
134 if (n2
!= NULL
&& n2
->type
== F_LINK
)
135 n2
->flags
&= ~F_MODE
;
137 if (n1
== NULL
&& n2
!= NULL
) {
139 mismatch(n1
, n2
, differs
, path
);
142 if (n1
!= NULL
&& n2
== NULL
) {
144 mismatch(n1
, n2
, differs
, path
);
147 if (n1
->type
!= n2
->type
) {
149 mismatch(n1
, n2
, differs
, path
);
152 if (FF(n1
, n2
, F_CKSUM
, cksum
))
154 if (FF(n1
, n2
, F_GID
, st_gid
))
156 if (FF(n1
, n2
, F_GNAME
, st_gid
))
158 if (FF(n1
, n2
, F_MODE
, st_mode
))
160 if (FF(n1
, n2
, F_NLINK
, st_nlink
))
162 if (FF(n1
, n2
, F_SIZE
, st_size
))
164 if (FS(n1
, n2
, F_SLINK
, slink
))
166 if (FM(n1
, n2
, F_TIME
, st_mtimespec
))
168 if (FF(n1
, n2
, F_UID
, st_uid
))
170 if (FF(n1
, n2
, F_UNAME
, st_uid
))
172 if (FS(n1
, n2
, F_MD5
, md5digest
))
174 if (FS(n1
, n2
, F_SHA1
, sha1digest
))
176 if (FS(n1
, n2
, F_RMD160
, rmd160digest
))
178 if (FS(n1
, n2
, F_SHA256
, sha256digest
))
180 if (FS(n1
, n2
, F_SHA384
, sha384digest
))
182 if (FS(n1
, n2
, F_SHA512
, sha512digest
))
184 if (FF(n1
, n2
, F_FLAGS
, st_flags
))
187 mismatch(n1
, n2
, differs
, path
);
193 walk_in_the_forest(NODE
*t1
, NODE
*t2
, char const *path
)
196 NODE
*c1
, *c2
, *n1
, *n2
;
209 while (c1
!= NULL
|| c2
!= NULL
) {
215 if (c1
!= NULL
&& c2
!= NULL
) {
216 if (c1
->type
!= F_DIR
&& c2
->type
== F_DIR
) {
219 } else if (c1
->type
== F_DIR
&& c2
->type
!= F_DIR
) {
223 i
= strcmp(c1
->name
, c2
->name
);
233 if (c1
== NULL
&& c2
->type
== F_DIR
) {
234 asprintf(&np
, "%s%s/", path
, c2
->name
);
235 i
= walk_in_the_forest(c1
, c2
, np
);
237 i
+= compare_nodes(c1
, c2
, path
);
238 } else if (c2
== NULL
&& c1
->type
== F_DIR
) {
239 asprintf(&np
, "%s%s/", path
, c1
->name
);
240 i
= walk_in_the_forest(c1
, c2
, np
);
242 i
+= compare_nodes(c1
, c2
, path
);
243 } else if (c1
== NULL
|| c2
== NULL
) {
244 i
= compare_nodes(c1
, c2
, path
);
245 } else if (c1
->type
== F_DIR
&& c2
->type
== F_DIR
) {
246 asprintf(&np
, "%s%s/", path
, c1
->name
);
247 i
= walk_in_the_forest(c1
, c2
, np
);
249 i
+= compare_nodes(c1
, c2
, path
);
251 i
= compare_nodes(c1
, c2
, path
);
261 mtree_specspec(FILE *fi
, FILE *fj
)
268 rval
= walk_in_the_forest(root1
, root2
, "");
269 rval
+= compare_nodes(root1
, root2
, "");
271 return (MISMATCHEXIT
);