BSD 2 development
[unix-history] / src / ckdir.c
CommitLineData
783c5c09
BJ
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
16int cflag = 1; /* Flag to verify */
17char cname[] = "check.sum"; /* Name of checksum files */
18int errs; /* Error count */
19
20main(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
49checkout(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
145cksum(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
164atoi(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
185any(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}