1/*- 2 * Copyright (c) 2003 Poul-Henning Kamp 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 2003 Poul-Henning Kamp 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h>
|
28__FBSDID("$FreeBSD: head/usr.sbin/mtree/specspec.c 133264 2004-08-07 10:04:29Z simokawa $");
| 28__FBSDID("$FreeBSD: head/usr.sbin/mtree/specspec.c 144295 2005-03-29 11:44:17Z tobez $");
|
29 30#include <err.h> 31#include <grp.h> 32#include <pwd.h> 33#include <stdio.h> 34#include <stdint.h> 35#include <unistd.h> 36#include "mtree.h" 37#include "extern.h" 38 39#define FF(a, b, c, d) \ 40 (((a)->flags & (c)) && ((b)->flags & (c)) && ((a)->d) != ((b)->d)) 41#define FS(a, b, c, d) \ 42 (((a)->flags & (c)) && ((b)->flags & (c)) && strcmp((a)->d,(b)->d)) 43#define FM(a, b, c, d) \ 44 (((a)->flags & (c)) && ((b)->flags & (c)) && memcmp(&(a)->d,&(b)->d, sizeof (a)->d)) 45 46static void 47shownode(NODE *n, int f, char const *path) 48{ 49 struct group *gr; 50 struct passwd *pw; 51 52 printf("%s%s %s", path, n->name, ftype(n->type)); 53 if (f & F_CKSUM) 54 printf(" cksum=%lu", n->cksum); 55 if (f & F_GID) 56 printf(" gid=%d", n->st_gid); 57 if (f & F_GNAME) { 58 gr = getgrgid(n->st_gid); 59 if (gr == NULL) 60 printf(" gid=%d", n->st_gid); 61 else 62 printf(" gname=%s", gr->gr_name); 63 } 64 if (f & F_MODE) 65 printf(" mode=%o", n->st_mode); 66 if (f & F_NLINK) 67 printf(" nlink=%d", n->st_nlink); 68 if (f & F_SIZE) 69 printf(" size=%jd", (intmax_t)n->st_size); 70 if (f & F_UID) 71 printf(" uid=%d", n->st_uid); 72 if (f & F_UNAME) { 73 pw = getpwuid(n->st_uid); 74 if (pw == NULL) 75 printf(" uid=%d", n->st_uid); 76 else 77 printf(" uname=%s", pw->pw_name); 78 } 79 if (f & F_MD5) 80 printf(" md5digest=%s", n->md5digest); 81 if (f & F_SHA1) 82 printf(" sha1digest=%s", n->sha1digest); 83 if (f & F_RMD160) 84 printf(" rmd160digest=%s", n->rmd160digest);
| 29 30#include <err.h> 31#include <grp.h> 32#include <pwd.h> 33#include <stdio.h> 34#include <stdint.h> 35#include <unistd.h> 36#include "mtree.h" 37#include "extern.h" 38 39#define FF(a, b, c, d) \ 40 (((a)->flags & (c)) && ((b)->flags & (c)) && ((a)->d) != ((b)->d)) 41#define FS(a, b, c, d) \ 42 (((a)->flags & (c)) && ((b)->flags & (c)) && strcmp((a)->d,(b)->d)) 43#define FM(a, b, c, d) \ 44 (((a)->flags & (c)) && ((b)->flags & (c)) && memcmp(&(a)->d,&(b)->d, sizeof (a)->d)) 45 46static void 47shownode(NODE *n, int f, char const *path) 48{ 49 struct group *gr; 50 struct passwd *pw; 51 52 printf("%s%s %s", path, n->name, ftype(n->type)); 53 if (f & F_CKSUM) 54 printf(" cksum=%lu", n->cksum); 55 if (f & F_GID) 56 printf(" gid=%d", n->st_gid); 57 if (f & F_GNAME) { 58 gr = getgrgid(n->st_gid); 59 if (gr == NULL) 60 printf(" gid=%d", n->st_gid); 61 else 62 printf(" gname=%s", gr->gr_name); 63 } 64 if (f & F_MODE) 65 printf(" mode=%o", n->st_mode); 66 if (f & F_NLINK) 67 printf(" nlink=%d", n->st_nlink); 68 if (f & F_SIZE) 69 printf(" size=%jd", (intmax_t)n->st_size); 70 if (f & F_UID) 71 printf(" uid=%d", n->st_uid); 72 if (f & F_UNAME) { 73 pw = getpwuid(n->st_uid); 74 if (pw == NULL) 75 printf(" uid=%d", n->st_uid); 76 else 77 printf(" uname=%s", pw->pw_name); 78 } 79 if (f & F_MD5) 80 printf(" md5digest=%s", n->md5digest); 81 if (f & F_SHA1) 82 printf(" sha1digest=%s", n->sha1digest); 83 if (f & F_RMD160) 84 printf(" rmd160digest=%s", n->rmd160digest);
|
| 85 if (f & F_SHA256) 86 printf(" sha256digest=%s", n->sha256digest);
|
85 if (f & F_FLAGS) 86 printf(" flags=%s", flags_to_string(n->st_flags)); 87 printf("\n"); 88} 89 90static int 91mismatch(NODE *n1, NODE *n2, int differ, char const *path) 92{ 93 94 if (n2 == NULL) { 95 shownode(n1, differ, path); 96 return (1); 97 } 98 if (n1 == NULL) { 99 printf("\t"); 100 shownode(n2, differ, path); 101 return (1); 102 } 103 if (!(differ & keys)) 104 return(0); 105 printf("\t\t"); 106 shownode(n1, differ, path); 107 printf("\t\t"); 108 shownode(n2, differ, path); 109 return (1); 110} 111 112static int 113compare_nodes(NODE *n1, NODE *n2, char const *path) 114{ 115 int differs; 116 117 if (n1 != NULL && n1->type == F_LINK) 118 n1->flags &= ~F_MODE; 119 if (n2 != NULL && n2->type == F_LINK) 120 n2->flags &= ~F_MODE; 121 differs = 0; 122 if (n1 == NULL && n2 != NULL) { 123 differs = n2->flags; 124 mismatch(n1, n2, differs, path); 125 return (1); 126 } 127 if (n1 != NULL && n2 == NULL) { 128 differs = n1->flags; 129 mismatch(n1, n2, differs, path); 130 return (1); 131 } 132 if (n1->type != n2->type) { 133 differs = 0; 134 mismatch(n1, n2, differs, path); 135 return (1); 136 } 137 if (FF(n1, n2, F_CKSUM, cksum)) 138 differs |= F_CKSUM; 139 if (FF(n1, n2, F_GID, st_gid)) 140 differs |= F_GID; 141 if (FF(n1, n2, F_GNAME, st_gid)) 142 differs |= F_GNAME; 143 if (FF(n1, n2, F_MODE, st_mode)) 144 differs |= F_MODE; 145 if (FF(n1, n2, F_NLINK, st_nlink)) 146 differs |= F_NLINK; 147 if (FF(n1, n2, F_SIZE, st_size)) 148 differs |= F_SIZE; 149 if (FS(n1, n2, F_SLINK, slink)) 150 differs |= F_SLINK; 151 if (FM(n1, n2, F_TIME, st_mtimespec)) 152 differs |= F_TIME; 153 if (FF(n1, n2, F_UID, st_uid)) 154 differs |= F_UID; 155 if (FF(n1, n2, F_UNAME, st_uid)) 156 differs |= F_UNAME; 157 if (FS(n1, n2, F_MD5, md5digest)) 158 differs |= F_MD5; 159 if (FS(n1, n2, F_SHA1, sha1digest)) 160 differs |= F_SHA1; 161 if (FS(n1, n2, F_RMD160, rmd160digest)) 162 differs |= F_RMD160;
| 87 if (f & F_FLAGS) 88 printf(" flags=%s", flags_to_string(n->st_flags)); 89 printf("\n"); 90} 91 92static int 93mismatch(NODE *n1, NODE *n2, int differ, char const *path) 94{ 95 96 if (n2 == NULL) { 97 shownode(n1, differ, path); 98 return (1); 99 } 100 if (n1 == NULL) { 101 printf("\t"); 102 shownode(n2, differ, path); 103 return (1); 104 } 105 if (!(differ & keys)) 106 return(0); 107 printf("\t\t"); 108 shownode(n1, differ, path); 109 printf("\t\t"); 110 shownode(n2, differ, path); 111 return (1); 112} 113 114static int 115compare_nodes(NODE *n1, NODE *n2, char const *path) 116{ 117 int differs; 118 119 if (n1 != NULL && n1->type == F_LINK) 120 n1->flags &= ~F_MODE; 121 if (n2 != NULL && n2->type == F_LINK) 122 n2->flags &= ~F_MODE; 123 differs = 0; 124 if (n1 == NULL && n2 != NULL) { 125 differs = n2->flags; 126 mismatch(n1, n2, differs, path); 127 return (1); 128 } 129 if (n1 != NULL && n2 == NULL) { 130 differs = n1->flags; 131 mismatch(n1, n2, differs, path); 132 return (1); 133 } 134 if (n1->type != n2->type) { 135 differs = 0; 136 mismatch(n1, n2, differs, path); 137 return (1); 138 } 139 if (FF(n1, n2, F_CKSUM, cksum)) 140 differs |= F_CKSUM; 141 if (FF(n1, n2, F_GID, st_gid)) 142 differs |= F_GID; 143 if (FF(n1, n2, F_GNAME, st_gid)) 144 differs |= F_GNAME; 145 if (FF(n1, n2, F_MODE, st_mode)) 146 differs |= F_MODE; 147 if (FF(n1, n2, F_NLINK, st_nlink)) 148 differs |= F_NLINK; 149 if (FF(n1, n2, F_SIZE, st_size)) 150 differs |= F_SIZE; 151 if (FS(n1, n2, F_SLINK, slink)) 152 differs |= F_SLINK; 153 if (FM(n1, n2, F_TIME, st_mtimespec)) 154 differs |= F_TIME; 155 if (FF(n1, n2, F_UID, st_uid)) 156 differs |= F_UID; 157 if (FF(n1, n2, F_UNAME, st_uid)) 158 differs |= F_UNAME; 159 if (FS(n1, n2, F_MD5, md5digest)) 160 differs |= F_MD5; 161 if (FS(n1, n2, F_SHA1, sha1digest)) 162 differs |= F_SHA1; 163 if (FS(n1, n2, F_RMD160, rmd160digest)) 164 differs |= F_RMD160;
|
| 165 if (FS(n1, n2, F_SHA256, sha256digest)) 166 differs |= F_SHA256;
|
163 if (FF(n1, n2, F_FLAGS, st_flags)) 164 differs |= F_FLAGS; 165 if (differs) { 166 mismatch(n1, n2, differs, path); 167 return (1); 168 } 169 return (0); 170} 171static int 172walk_in_the_forest(NODE *t1, NODE *t2, char const *path) 173{ 174 int r, i; 175 NODE *c1, *c2, *n1, *n2; 176 char *np; 177 178 r = 0; 179 180 if (t1 != NULL) 181 c1 = t1->child; 182 else 183 c1 = NULL; 184 if (t2 != NULL) 185 c2 = t2->child; 186 else 187 c2 = NULL; 188 while (c1 != NULL || c2 != NULL) { 189 n1 = n2 = NULL; 190 if (c1 != NULL) 191 n1 = c1->next; 192 if (c2 != NULL) 193 n2 = c2->next; 194 if (c1 != NULL && c2 != NULL) { 195 if (c1->type != F_DIR && c2->type == F_DIR) { 196 n2 = c2; 197 c2 = NULL; 198 } else if (c1->type == F_DIR && c2->type != F_DIR) { 199 n1 = c1; 200 c1 = NULL; 201 } else { 202 i = strcmp(c1->name, c2->name); 203 if (i > 0) { 204 n1 = c1; 205 c1 = NULL; 206 } else if (i < 0) { 207 n2 = c2; 208 c2 = NULL; 209 } 210 } 211 } 212 if (c1 == NULL && c2->type == F_DIR) { 213 asprintf(&np, "%s%s/", path, c2->name); 214 i = walk_in_the_forest(c1, c2, np); 215 free(np);
| 167 if (FF(n1, n2, F_FLAGS, st_flags)) 168 differs |= F_FLAGS; 169 if (differs) { 170 mismatch(n1, n2, differs, path); 171 return (1); 172 } 173 return (0); 174} 175static int 176walk_in_the_forest(NODE *t1, NODE *t2, char const *path) 177{ 178 int r, i; 179 NODE *c1, *c2, *n1, *n2; 180 char *np; 181 182 r = 0; 183 184 if (t1 != NULL) 185 c1 = t1->child; 186 else 187 c1 = NULL; 188 if (t2 != NULL) 189 c2 = t2->child; 190 else 191 c2 = NULL; 192 while (c1 != NULL || c2 != NULL) { 193 n1 = n2 = NULL; 194 if (c1 != NULL) 195 n1 = c1->next; 196 if (c2 != NULL) 197 n2 = c2->next; 198 if (c1 != NULL && c2 != NULL) { 199 if (c1->type != F_DIR && c2->type == F_DIR) { 200 n2 = c2; 201 c2 = NULL; 202 } else if (c1->type == F_DIR && c2->type != F_DIR) { 203 n1 = c1; 204 c1 = NULL; 205 } else { 206 i = strcmp(c1->name, c2->name); 207 if (i > 0) { 208 n1 = c1; 209 c1 = NULL; 210 } else if (i < 0) { 211 n2 = c2; 212 c2 = NULL; 213 } 214 } 215 } 216 if (c1 == NULL && c2->type == F_DIR) { 217 asprintf(&np, "%s%s/", path, c2->name); 218 i = walk_in_the_forest(c1, c2, np); 219 free(np);
|
216 i = compare_nodes(c1, c2, path);
| 220 i += compare_nodes(c1, c2, path);
|
217 } else if (c2 == NULL && c1->type == F_DIR) { 218 asprintf(&np, "%s%s/", path, c1->name); 219 i = walk_in_the_forest(c1, c2, np); 220 free(np);
| 221 } else if (c2 == NULL && c1->type == F_DIR) { 222 asprintf(&np, "%s%s/", path, c1->name); 223 i = walk_in_the_forest(c1, c2, np); 224 free(np);
|
221 i = compare_nodes(c1, c2, path);
| 225 i += compare_nodes(c1, c2, path);
|
222 } else if (c1 == NULL || c2 == NULL) { 223 i = compare_nodes(c1, c2, path); 224 } else if (c1->type == F_DIR && c2->type == F_DIR) { 225 asprintf(&np, "%s%s/", path, c1->name); 226 i = walk_in_the_forest(c1, c2, np); 227 free(np);
| 226 } else if (c1 == NULL || c2 == NULL) { 227 i = compare_nodes(c1, c2, path); 228 } else if (c1->type == F_DIR && c2->type == F_DIR) { 229 asprintf(&np, "%s%s/", path, c1->name); 230 i = walk_in_the_forest(c1, c2, np); 231 free(np);
|
228 i = compare_nodes(c1, c2, path);
| 232 i += compare_nodes(c1, c2, path);
|
229 } else { 230 i = compare_nodes(c1, c2, path); 231 } 232 r += i; 233 c1 = n1; 234 c2 = n2; 235 } 236 return (r); 237} 238 239int 240mtree_specspec(FILE *fi, FILE *fj) 241{ 242 int rval; 243 NODE *root1, *root2; 244 245 root1 = mtree_readspec(fi); 246 root2 = mtree_readspec(fj); 247 rval = walk_in_the_forest(root1, root2, ""); 248 rval += compare_nodes(root1, root2, ""); 249 if (rval > 0) 250 return (MISMATCHEXIT); 251 return (0); 252}
| 233 } else { 234 i = compare_nodes(c1, c2, path); 235 } 236 r += i; 237 c1 = n1; 238 c2 = n2; 239 } 240 return (r); 241} 242 243int 244mtree_specspec(FILE *fi, FILE *fj) 245{ 246 int rval; 247 NODE *root1, *root2; 248 249 root1 = mtree_readspec(fi); 250 root2 = mtree_readspec(fj); 251 rval = walk_in_the_forest(root1, root2, ""); 252 rval += compare_nodes(root1, root2, ""); 253 if (rval > 0) 254 return (MISMATCHEXIT); 255 return (0); 256}
|