Skip to content

Commit 38f85bf

Browse files
committed
Initial commit
Exercise completed.
1 parent fd25ba7 commit 38f85bf

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed

chapter08/8-5.c

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/*
2+
* Exercise 8-5. Modify the fsize program to print the other information contained in the inode entry.
3+
* By Faisal Saadatmand
4+
*/
5+
6+
#define _XOPEN_SOURCE /* for modern Unix sys/stat.h */
7+
8+
#include <stdio.h>
9+
#include <string.h>
10+
#include <unistd.h>
11+
#include <fcntl.h> /* flags for read and write */
12+
#include <sys/types.h> /* typedefs */
13+
#include <sys/stat.h> /* structure returned by stat */
14+
#include "dirent.h"
15+
#include <stdlib.h> /* for malloc */
16+
#include <time.h>
17+
18+
#include <sys/stat.h> /* structure returned by stat */
19+
20+
#define MAX_PATH 1024
21+
#define MAX_TIME 60
22+
#ifndef DIRSIZE
23+
#define DIRSIZE 14
24+
#endif
25+
26+
struct direct /* directory */
27+
{
28+
ino_t d_ino; /* inode number */
29+
char d_name[DIRSIZE]; /* long name does not have '\0' */
30+
};
31+
32+
/* functions */
33+
void fsize(char *);
34+
void dirwalk(char *, void (*fcn)(char *));
35+
int fstat(int fd, struct stat *);
36+
void timefmt(char *, int, time_t *);
37+
38+
/* timefmt: format unix time into local time */
39+
void timefmt(char *buffer, int bufsize, time_t *utime)
40+
{
41+
struct tm brokentime;
42+
struct tm *tp = &brokentime;
43+
44+
tp = localtime(utime); /* Unix time to broken local time time */
45+
strftime(buffer, bufsize, "%b %d %H:%M ", tp);
46+
}
47+
48+
/* fsize: print size of file name */
49+
void fsize(char *name)
50+
{
51+
struct stat stbuf;
52+
char *time; /* formated time */
53+
54+
if (stat(name, &stbuf) == -1) {
55+
fprintf(stderr, "fsize: can't access %s\n", name);
56+
return;
57+
}
58+
if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
59+
dirwalk(name, fsize);
60+
61+
if ((time = (char *) malloc(MAX_TIME)) == NULL) {
62+
fprintf(stderr, "fsize: can't allocate memory to buffer %s\n", name);
63+
exit(EXIT_FAILURE);
64+
}
65+
66+
timefmt(time, MAX_TIME, &stbuf.st_mtime);
67+
printf("%o %lu %u %u %8ld %s %s\n", stbuf.st_mode, stbuf.st_nlink,
68+
stbuf.st_uid, stbuf.st_gid, stbuf.st_size, time, name);
69+
free(time);
70+
}
71+
72+
/* dirwalk: apply fcn to all files in dir */
73+
void dirwalk(char *dir, void (*fcn)(char *name))
74+
{
75+
char name[MAX_PATH];
76+
Dirent *dp;
77+
DIR *dfd;
78+
79+
if ((dfd = opendir(dir)) == NULL) {
80+
fprintf(stderr, "dirwalk: can't open %s\n", dir);
81+
return;
82+
}
83+
while ((dp = readdir(dfd)) != NULL) {
84+
if (strcmp(dp->name, ".") == 0
85+
|| strcmp(dp->name, "..") == 0)
86+
continue; /* skip self and parent */
87+
if (strlen(dir) + strlen(dp->name) + 2 > sizeof(name))
88+
fprintf(stderr, "dirwalk: name %s/%s too long\n", dir, dp->name);
89+
else {
90+
sprintf(name, "%s/%s", dir, dp->name);
91+
(*fcn)(name);
92+
}
93+
}
94+
closedir(dfd);
95+
}
96+
97+
/* opendir: open a directory for readdir calls */
98+
DIR *opendir(char *dirname)
99+
{
100+
int fd;
101+
struct stat stbuf;
102+
DIR *dp;
103+
104+
if ((fd = open(dirname, O_RDONLY, 0)) == -1
105+
|| fstat(fd, &stbuf) == -1
106+
|| (stbuf.st_mode & S_IFMT) != S_IFDIR
107+
|| (dp = (DIR *) malloc(sizeof(DIR))) == NULL)
108+
return NULL;
109+
dp->fd = fd;
110+
return dp;
111+
}
112+
113+
/* closedir: close directory opened by opendir */
114+
void closedir(DIR *dp)
115+
{
116+
if (dp) {
117+
close(dp->fd);
118+
free(dp);
119+
}
120+
}
121+
122+
/* readdir: read directory entries in sequence */
123+
Dirent *readdir(DIR *dp)
124+
{
125+
struct direct dirbuf; /* local directory structure */
126+
static Dirent d; /* return: portable structure */
127+
128+
while (read(dp->fd, (char *) &dirbuf, sizeof(dirbuf)) == sizeof(dirbuf)) {
129+
if (dirbuf.d_ino == 0) /* slot not in use */
130+
continue;
131+
d.ino = dirbuf.d_ino;
132+
strncpy(d.name, dirbuf.d_name, DIRSIZE);
133+
d.name[DIRSIZE - 1] = '\0'; /* ensure termination */
134+
return &d;
135+
}
136+
return NULL;
137+
}
138+
139+
/* print file size */
140+
int main(int argc, char **argv) /* **argv == *argv[] */
141+
{
142+
if (argc == 1) /* default: current directory */
143+
fsize(".");
144+
else
145+
while (--argc > 0)
146+
fsize(*++argv);
147+
return 0;
148+
}

0 commit comments

Comments
 (0)