]> diplodocus.org Git - nmh/blob - docs/historical/mh-jun-1982/Extras/libh/gwd.c
Replaced use of snprintf() with memcpy()/memmove().
[nmh] / docs / historical / mh-jun-1982 / Extras / libh / gwd.c
1 #ifdef COMMENT
2 Proprietary Rand Corporation, 1981.
3 Further distribution of this software
4 subject to the terms of the Rand
5 license agreement.
6 #endif
7
8 #include "../h/stat.h"
9 #include "../h/dirent.h"
10
11 struct dirinfo {
12 struct dirent dir;
13 char null;
14 int dotino;
15 int dotdotino;
16 };
17
18 char *rootlist[] {
19 "/",
20 "/rnd/",
21 "/mnt/",
22 "/sys/",
23 "/bak/",
24 "/fsd/",
25 0
26 };
27 gwd()
28 {
29 return(fullpath(0));
30 }
31
32 fullpath(str)
33 char *str;
34 {
35 static char wdbuf[128];
36 struct dirinfo d;
37 register char *wp, *cp, **cpp;
38 int fino;
39 char *savewp, *markwp;
40 int dotdev;
41 struct inode statb;
42
43 wp = &wdbuf + 1;
44 *--wp = 0;
45 markwp = 0;
46 if (str) {
47 wp = prepend(str, wp);
48 if (*wp == '/') return(wp);
49 *--wp = 0;
50 markwp = wp;
51 }
52 fino = 0;
53
54 for (;;) {
55 wp = scandir(&d, fino, wp);
56 if (d.dotino != d.dotdotino) {
57 fino = d.dotino;
58 chdir("..");
59 continue;
60 }
61 savewp = wp;
62 if (d.dotino != ROOTINO) break; /* error */
63 stat(".", &statb);
64 dotdev = statb.i_dev;
65 for (cpp = rootlist; cp = *cpp++; ) {
66 if (stat(cp, &statb) < 0) continue;
67 if (statb.i_dev == dotdev) {
68 wp = prepend(cp, wp);
69 break;
70 }
71 }
72 break;
73 }
74 chdir(savewp);
75 if (markwp) *markwp = '/';
76 return(wp);
77 }
78
79 scandir(dp, fileino, endwhere)
80 struct dirinfo *dp;
81 char *endwhere;
82 {
83 register struct dirinfo *d;
84 register char *cp, *wp;
85 int fh;
86
87 d = dp;
88 d->dotino = 0;
89 d->dotdotino = 0;
90 if (fileino == 0) wp = endwhere;
91 else wp = 0;
92 fh = open(".", 0);
93 if (fh < 0) return(wp);
94 while ((!d->dotino || !d->dotdotino || !wp) &&
95 read(fh, &d->dir, sizeof d->dir) == sizeof d->dir) {
96 if (d->dir.d_ino == NULLINO) continue;
97 if (!d->dotino && equal(d->dir.d_name, "."))
98 d->dotino = d->dir.d_ino;
99 else if (!d->dotdotino && equal(d->dir.d_name, ".."))
100 d->dotdotino = d->dir.d_ino;
101 else if (!wp && d->dir.d_ino == fileino) {
102 /* ensure name is null term'd */
103 d->null = 0;
104 wp = endwhere;
105 /* separate with '/' */
106 if (*wp) *--wp = '/';
107 wp = prepend(d->dir.d_name, wp);
108 }
109 }
110 close(fh);
111 return(wp);
112 }
113
114 prepend(prefix, endwhere)
115 char *prefix, *endwhere;
116 {
117 register char *cp, *wp;
118
119 for (cp = prefix; *cp++; );
120 --cp;
121 for (wp = endwhere; cp > prefix; *--wp = *--cp);
122 return(wp);
123 }