1 /*- 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)compare.c 5.7 (Berkeley) 05/25/90"; 10 #endif /* not lint */ 11 12 #include <sys/param.h> 13 #include <sys/stat.h> 14 #include <fts.h> 15 #include <errno.h> 16 #include <stdio.h> 17 #include <time.h> 18 #include "mtree.h" 19 20 #define LABEL \ 21 if (!label++) \ 22 (void)printf("%s: ", RP(p)); \ 23 24 compare(name, s, p) 25 char *name; 26 register NODE *s; 27 register FTSENT *p; 28 { 29 extern int exitval, uflag; 30 int label; 31 char *ftype(), *inotype(), *rlink(); 32 33 label = 0; 34 switch(s->type) { 35 case F_BLOCK: 36 if (!S_ISBLK(p->fts_statb.st_mode)) 37 goto typeerr; 38 break; 39 case F_CHAR: 40 if (!S_ISCHR(p->fts_statb.st_mode)) 41 goto typeerr; 42 break; 43 case F_DIR: 44 if (!S_ISDIR(p->fts_statb.st_mode)) 45 goto typeerr; 46 break; 47 case F_FIFO: 48 if (!S_ISFIFO(p->fts_statb.st_mode)) 49 goto typeerr; 50 break; 51 case F_FILE: 52 if (!S_ISREG(p->fts_statb.st_mode)) 53 goto typeerr; 54 break; 55 case F_LINK: 56 if (!S_ISLNK(p->fts_statb.st_mode)) 57 goto typeerr; 58 break; 59 case F_SOCK: 60 if (!S_ISFIFO(p->fts_statb.st_mode)) { 61 typeerr: LABEL; 62 (void)printf("\n\ttype (%s, %s)", 63 ftype(s->type), inotype(p->fts_statb.st_mode)); 64 } 65 break; 66 } 67 if (s->flags & F_MODE && s->st_mode != (p->fts_statb.st_mode & MBITS)) { 68 LABEL; 69 (void)printf("\n\tpermissions (%#o, %#o%s", 70 s->st_mode, p->fts_statb.st_mode & MBITS, uflag ? "" : ")"); 71 if (uflag) 72 if (chmod(p->fts_accpath, s->st_mode)) 73 (void)printf(", not modified: %s)", 74 strerror(errno)); 75 else 76 (void)printf(", modified)"); 77 } 78 if (s->flags & F_OWNER && s->st_uid != p->fts_statb.st_uid) { 79 LABEL; 80 (void)printf("\n\towner (%u, %u%s", 81 s->st_uid, p->fts_statb.st_uid, uflag ? "" : ")"); 82 if (uflag) 83 if (chown(p->fts_accpath, s->st_uid, -1)) 84 (void)printf(", not modified: %s)", 85 strerror(errno)); 86 else 87 (void)printf(", modified)"); 88 } 89 if (s->flags & F_GROUP && s->st_gid != p->fts_statb.st_gid) { 90 LABEL; 91 (void)printf("\n\tgroup (%u, %u%s", 92 s->st_gid, p->fts_statb.st_gid, uflag ? "" : ")"); 93 if (uflag) 94 if (chown(p->fts_accpath, -1, s->st_gid)) 95 (void)printf(", not modified: %s)", 96 strerror(errno)); 97 else 98 (void)printf(", modified)"); 99 } 100 if (s->flags & F_NLINK && s->type != F_DIR && 101 s->st_nlink != p->fts_statb.st_nlink) { 102 LABEL; 103 (void)printf("\n\tlink count (%u, %u)", 104 s->st_nlink, p->fts_statb.st_nlink); 105 } 106 if (s->flags & F_SIZE && s->st_size != p->fts_statb.st_size) { 107 LABEL; 108 (void)printf("\n\tsize (%ld, %ld)", 109 s->st_size, p->fts_statb.st_size); 110 } 111 if (s->flags & F_SLINK) { 112 char *cp; 113 114 if (strcmp(cp = rlink(name), s->slink)) { 115 LABEL; 116 (void)printf("\n\tlink ref (%s, %s)", cp, s->slink); 117 } 118 } 119 if (s->flags & F_TIME && s->st_mtime != p->fts_statb.st_mtime) { 120 LABEL; 121 (void)printf("\n\tmodification time (%.24s, ", 122 ctime(&s->st_mtime)); 123 (void)printf("%.24s)", ctime(&p->fts_statb.st_mtime)); 124 } 125 if (label) { 126 exitval = 2; 127 putchar('\n'); 128 } 129 } 130 131 char * 132 inotype(type) 133 mode_t type; 134 { 135 switch(type & S_IFMT) { 136 case S_IFBLK: 137 return("block"); 138 case S_IFCHR: 139 return("char"); 140 case S_IFDIR: 141 return("dir"); 142 case S_IFREG: 143 return("file"); 144 case S_IFLNK: 145 return("link"); 146 case S_IFSOCK: 147 return("socket"); 148 default: 149 return("unknown"); 150 } 151 /* NOTREACHED */ 152 } 153 154 char * 155 ftype(type) 156 u_int type; 157 { 158 switch(type) { 159 case F_BLOCK: 160 return("block"); 161 case F_CHAR: 162 return("char"); 163 case F_DIR: 164 return("dir"); 165 case F_FIFO: 166 return("fifo"); 167 case F_FILE: 168 return("file"); 169 case F_LINK: 170 return("link"); 171 case F_SOCK: 172 return("socket"); 173 default: 174 return("unknown"); 175 } 176 /* NOTREACHED */ 177 } 178 179 char * 180 rlink(name) 181 char *name; 182 { 183 register int len; 184 static char lbuf[MAXPATHLEN]; 185 186 len = readlink(name, lbuf, sizeof(lbuf)); 187 if (len == -1) { 188 (void)fprintf(stderr, "mtree: %s: %s.\n", 189 name, strerror(errno)); 190 exit(1); 191 } 192 lbuf[len] = '\0'; 193 return(lbuf); 194 } 195