xref: /original-bsd/bin/df/df.c (revision d25e1985)
1 static char *sccsid = "@(#)df.c	4.1 (Berkeley) 10/01/80";
2 #include <stdio.h>
3 #include <fstab.h>
4 #include <sys/param.h>
5 #include <sys/filsys.h>
6 #include <sys/fblk.h>
7 
8 #define NFS	20	/* Max number of filesystems */
9 
10 
11 struct {
12 	char path[32];
13 	char spec[32];
14 } mtab[NFS];
15 char root[32];
16 
17 char *mpath();
18 
19 daddr_t	blkno	= 1;
20 
21 int	lflag;
22 int	iflag;
23 
24 struct	filsys sblock;
25 
26 int	fi;
27 daddr_t	alloc();
28 
29 main(argc, argv)
30 char **argv;
31 {
32 	int i;
33 	FILE *f = fopen(FSTAB, "r");
34 	char buf[128];
35 	struct	fstab	fs;
36 
37 	while (argc >= 1 && argv[1][0]=='-') {
38 		switch(argv[1][1]) {
39 
40 		case 'l':
41 			lflag++;
42 			break;
43 
44 		case 'i':
45 			iflag++;
46 			break;
47 
48 		default:
49 			fprintf(stderr, "usage: df [ -il ] [ filsys... ]\n");
50 			exit(0);
51 		}
52 		argc--, argv++;
53 	}
54 
55 	if ((i=open("/etc/mtab", 0)) >= 0) {
56 		read(i, mtab, sizeof mtab);	/* Probably returns short */
57 		close(i);
58 	}
59 	printf("Filesystem  Mounted on  blocks\t  used\t  free");
60 	if (lflag)
61 		printf("\thardway");
62 	printf("\t%% used");
63 	if (iflag)
64 		printf("\tiused\tifree\t%%iused");
65 	putchar('\n');
66 	if(argc <= 1) {
67 		if (f == NULL)
68 			perror(FSTAB), exit(1);
69 		while (!feof(f)){
70 			fscanf(f, FSTABFMT, FSTABARG(&fs));
71 			if (root[0] == 0)
72 				strcpy(root, fs.fs_spec);
73 			dfree(fs.fs_spec);
74 		}
75 		exit(0);
76 	}
77 
78 	if (f){
79 		fscanf(f, FSTABFMT, FSTABARG(&fs));
80 		strcpy(root, fs.fs_spec);
81 	}
82 	for(i=1; i<argc; i++) {
83 		dfree(argv[i]);
84 	}
85 }
86 
87 dfree(file)
88 char *file;
89 {
90 	daddr_t i;
91 	long	blocks;
92 	long	free;
93 	long	used;
94 	long	hardway;
95 	char	*mp;
96 
97 	fi = open(file, 0);
98 	if(fi < 0) {
99 		fprintf(stderr,"cannot open %s\n", file);
100 		return;
101 	}
102 	sync();
103 	bread(1L, (char *)&sblock, sizeof(sblock));
104 	printf("%-12.12s%s", file, mp = mpath(file));
105 	if (strlen(mp) < 4)
106 		putchar('\t');
107 
108 	blocks = (long) sblock.s_fsize - (long)sblock.s_isize;
109 	free = sblock.s_tfree;
110 	used = blocks - free;
111 
112 	printf("\t%6ld", blocks);
113 	printf("\t%6ld", used);
114 	printf("\t%6ld", free);
115 	if (lflag) {
116 		hardway = 0;
117 		while(alloc())
118 			hardway++;
119 		printf("\t%6ld", free=hardway);
120 	}
121 	printf("\t%5.0f%%", (double) used / (double)blocks * 100.0);
122 	if (iflag) {
123 		int inodes = (sblock.s_isize - 2) * INOPB;
124 		used = inodes - sblock.s_tinode;
125 		printf("\t%5ld\t%5ld\t%5.0f%%", used, sblock.s_tinode, (double)used/(double)inodes*100.0);
126 	}
127 	printf("\n");
128 	close(fi);
129 }
130 
131 daddr_t
132 alloc()
133 {
134 	int i;
135 	daddr_t b;
136 	struct fblk buf;
137 
138 	i = --sblock.s_nfree;
139 	if(i<0 || i>=NICFREE) {
140 		printf("bad free count, b=%D\n", blkno);
141 		return(0);
142 	}
143 	b = sblock.s_free[i];
144 	if(b == 0)
145 		return(0);
146 	if(b<sblock.s_isize || b>=sblock.s_fsize) {
147 		printf("bad free block (%D)\n", b);
148 		return(0);
149 	}
150 	if(sblock.s_nfree <= 0) {
151 		bread(b, (char *)&buf, sizeof(buf));
152 		blkno = b;
153 		sblock.s_nfree = buf.df_nfree;
154 		for(i=0; i<NICFREE; i++)
155 			sblock.s_free[i] = buf.df_free[i];
156 	}
157 	return(b);
158 }
159 
160 bread(bno, buf, cnt)
161 daddr_t bno;
162 char *buf;
163 {
164 	int n;
165 	extern errno;
166 
167 	lseek(fi, bno<<BSHIFT, 0);
168 	if((n=read(fi, buf, cnt)) != cnt) {
169 		printf("\nread error bno = %ld\n", bno);
170 		printf("count = %d; errno = %d\n", n, errno);
171 		exit(0);
172 	}
173 }
174 
175 /*
176  * Given a name like /dev/rrp0h, returns the mounted path, like /usr.
177  */
178 char *mpath(file)
179 char *file;
180 {
181 	register int i;
182 
183 	if (eq(file, root))
184 		return "/";
185 	for (i=0; i<NFS; i++)
186 		if (eq(file, mtab[i].spec))
187 			return mtab[i].path;
188 	return "";
189 }
190 
191 eq(f1, f2)
192 char *f1, *f2;
193 {
194 	if (strncmp(f1, "/dev/", 5) == 0)
195 		f1 += 5;
196 	if (strncmp(f2, "/dev/", 5) == 0)
197 		f2 += 5;
198 	if (strcmp(f1, f2) == 0)
199 		return 1;
200 	if (*f1 == 'r' && strcmp(f1+1, f2) == 0)
201 		return 1;
202 	if (*f2 == 'r' && strcmp(f1, f2+1) == 0)
203 		return 1;
204 	if (*f1 == 'r' && *f2 == 'r' && strcmp(f1+1, f2+1) == 0)
205 		return 1;
206 	return 0;
207 }
208