]> git.zerfleddert.de Git - micropolis/blob - src/tcl/compat/opendir.c
let the monster survive if it is born in a river
[micropolis] / src / tcl / compat / opendir.c
1 /*
2 * opendir.c --
3 *
4 * This file provides dirent-style directory-reading procedures
5 * for V7 Unix systems that don't have such procedures. The
6 * origin of this code is unclear, but it seems to have come
7 * originally from Larry Wall.
8 *
9 */
10
11 #include <tclint.h>
12 #include <tclunix.h>
13
14 #undef DIRSIZ
15 #define DIRSIZ(dp) \
16 ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
17
18 /*
19 * open a directory.
20 */
21 DIR *
22 opendir(name)
23 char *name;
24 {
25 register DIR *dirp;
26 register int fd;
27 char *myname;
28
29 myname = ((*name == '\0') ? "." : name);
30 if ((fd = open(myname, 0, 0)) == -1)
31 return NULL;
32 if ((dirp = (DIR *)ckalloc(sizeof(DIR))) == NULL) {
33 close (fd);
34 return NULL;
35 }
36 dirp->dd_fd = fd;
37 dirp->dd_loc = 0;
38 return dirp;
39 }
40
41 /*
42 * read an old style directory entry and present it as a new one
43 */
44 #ifndef pyr
45 #define ODIRSIZ 14
46
47 struct olddirect {
48 ino_t od_ino;
49 char od_name[ODIRSIZ];
50 };
51 #else /* a Pyramid in the ATT universe */
52 #define ODIRSIZ 248
53
54 struct olddirect {
55 long od_ino;
56 short od_fill1, od_fill2;
57 char od_name[ODIRSIZ];
58 };
59 #endif
60
61 /*
62 * get next entry in a directory.
63 */
64 struct dirent *
65 readdir(dirp)
66 register DIR *dirp;
67 {
68 register struct olddirect *dp;
69 static struct dirent dir;
70
71 for (;;) {
72 if (dirp->dd_loc == 0) {
73 dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf,
74 DIRBLKSIZ);
75 if (dirp->dd_size <= 0)
76 return NULL;
77 }
78 if (dirp->dd_loc >= dirp->dd_size) {
79 dirp->dd_loc = 0;
80 continue;
81 }
82 dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
83 dirp->dd_loc += sizeof(struct olddirect);
84 if (dp->od_ino == 0)
85 continue;
86 dir.d_ino = dp->od_ino;
87 strncpy(dir.d_name, dp->od_name, ODIRSIZ);
88 dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
89 dir.d_namlen = strlen(dir.d_name);
90 dir.d_reclen = DIRSIZ(&dir);
91 return (&dir);
92 }
93 }
94
95 /*
96 * close a directory.
97 */
98 void
99 closedir(dirp)
100 register DIR *dirp;
101 {
102 close(dirp->dd_fd);
103 dirp->dd_fd = -1;
104 dirp->dd_loc = 0;
105 ckfree((char *) dirp);
106 }
Impressum, Datenschutz