1: /* Copyright (c) 1979 Regents of the University of California */ 2: #include <retrofit.h> 3: #include <sys/types.h> 4: #include <sys/dir.h> 5: #include <sys/stat.h> 6: #include <stdio.h> 7: 8: /* 9: * Checksum the indicated directory, creating the file "check.sum" 10: * with names and int sums stored inside, one per line. The -c 11: * option causes the directory checksums to be verified. 12: */ 13: 14: #define equal(a, b) (strcmp(a, b) == 0) 15: 16: int cflag = 1; /* Flag to verify */ 17: char cname[] = "check.sum"; /* Name of checksum files */ 18: int errs; /* Error count */ 19: 20: main(argc, argv) 21: char **argv; 22: { 23: register char *cp; 24: 25: if (argc == 2 && equal(argv[1], "-c")) { 26: cflag = 0; 27: argc--, argv++; 28: } 29: if (argc < 2) { 30: checkout("."); 31: exit(errs); 32: } 33: while (--argc) { 34: cp = *++argv; 35: if (equal(cp, "-c")) { 36: cflag++; 37: continue; 38: } 39: checkout(cp); 40: } 41: exit(errs); 42: } 43: 44: /* 45: * Checkout a directory. 46: * The fork is necessary to preserve the current directory. 47: */ 48: 49: checkout(dir) 50: char dir[]; 51: { 52: int s, pid; 53: char ename[DIRSIZ+1], linebuf[BUFSIZ]; 54: FILE *cf, *df, *ef; 55: register int sum, c; 56: struct direct dirent; 57: register char *cp, *cp2; 58: 59: pid = fork(); 60: if (pid == -1) { 61: perror("fork"); 62: errs++; 63: return; 64: } 65: if (pid > 0) { 66: while (wait(&s) != pid) 67: ; 68: if (s != 0) 69: errs++; 70: return; 71: } 72: errs = 0; 73: fprintf(stderr, "%s:\n", dir); 74: if (chdir(dir) < 0) { 75: perror(dir); 76: exit(1); 77: } 78: if (cflag) { 79: if ((cf = fopen(cname, "r")) == NULL) { 80: perror(cname); 81: exit(1); 82: } 83: while (fgets(linebuf, BUFSIZ, cf) != NULL) { 84: for (cp = linebuf, cp2 = ename; *cp != ' '; 85: *cp2++ = *cp++) 86: ; 87: *cp2 = '\0'; 88: if (equal(ename, cname)) 89: continue; 90: if ((ef = fopen(ename, "r")) == NULL) { 91: perror(ename); 92: errs++; 93: continue; 94: } 95: c = cksum(ef); 96: fclose(ef); 97: sum = atoi(cp); 98: if (sum != c) { 99: printf("Checksum error: \"%s\" is %d not %d\n", 100: ename, c, sum); 101: errs++; 102: } 103: } 104: exit(errs); 105: } 106: if ((cf = fopen(cname, "w")) == NULL) { 107: perror(cname); 108: exit(1); 109: } 110: if ((df = fopen("", "r")) == NULL) { 111: perror(dir); 112: exit(1); 113: } 114: while (fread((char *) &dirent, sizeof dirent, 1, df) == 1) { 115: struct stat stb; 116: if (dirent.d_ino == 0) 117: continue; 118: for (cp = dirent.d_name, cp2 = ename; *cp && 119: cp-dirent.d_name < DIRSIZ; *cp2++ = *cp++) 120: ; 121: *cp2 = '\0'; 122: if (equal(ename, cname)) 123: continue; 124: if ((ef = fopen(ename, "r")) == NULL) { 125: perror(ename); 126: errs++; 127: continue; 128: } 129: fstat(fileno(ef), &stb); 130: if ((stb.st_mode & S_IFMT) != S_IFREG) { 131: fclose(ef); 132: continue; 133: } 134: sum = cksum(ef); 135: fclose(ef); 136: fprintf(cf, "%s %d\n", ename, sum); 137: } 138: exit(errs); 139: } 140: 141: /* 142: * Checksum the passed file. Return the sum of all of its bytes. 143: */ 144: 145: cksum(f) 146: FILE *f; 147: { 148: register int sum, c; 149: 150: sum = 0; 151: while ((c = getc(f)) != EOF) 152: sum += c; 153: if (sum < 0) 154: sum = -sum; 155: if (sum < 0) 156: sum = 0; 157: return(sum); 158: } 159: 160: /* 161: * Convert the passed string to decimal. 162: */ 163: 164: atoi(cp) 165: register char *cp; 166: { 167: register int sum, sign; 168: 169: while (any(*cp, " \t")) 170: cp++; 171: if (*cp == '-') 172: sign = -1; 173: else 174: sign = 1; 175: sum = 0; 176: while (any(*cp, "0123456789")) 177: sum = sum*10 + *cp++ - '0'; 178: return(sign*sum); 179: } 180: 181: /* 182: * Is c any of *cp ? 183: */ 184: 185: any(c, cp) 186: register int c; 187: register char *cp; 188: { 189: while (*cp) 190: if (c == *cp++) 191: return(1); 192: return(0); 193: }