Start development on BSD 2
[unix-history] / .ref-BSD-1 / ashell / sh_glob.c
CommitLineData
1a5078b8
BJ
1#include "sh.h"
2
3#define STRSIZ 522
4#define PTHSIZ 100
5
6static char ab[STRSIZ];
7static char *ava[200];
8static char **av;
9static char *string;
10static int ncoll;
11
12static char gpath[100], *gpathp;
13static int globbed;
14static char *entp;
15
16static int stbuff[18];
17
18char **
19glob(v)
20 register char *v[];
21{
22
23 if (adrof("noglob"))
24 return (v);
25 ginit();
26 while (*v)
27 collect(*v++);
28 *av++ = 0;
29 return (ncoll == 0 ? 0 : &ava[2]);
30}
31
32ginit()
33{
34 av = &ava[2];
35 string = ab;
36 ncoll = 0;
37 globbed = 0;
38 gpathp = gpath;
39}
40
41collect(as)
42{
43 char **oav;
44
45 oav = av;
46 globbed = 0;
47 expand(as);
48 sort(oav);
49}
50
51sort(oav)
52char **oav;
53{
54 register char **p1, **p2, **c;
55
56 p1 = oav;
57 while (p1 < av-1) {
58 p2 = p1;
59 while(++p2 < av) {
60 if (strcmp(*p1, *p2) > 0) {
61 c = *p1;
62 *p1 = *p2;
63 *p2 = c;
64 }
65 }
66 p1++;
67 }
68}
69
70expand(as)
71char *as;
72{
73 register char *cs;
74 char *sgpathp;
75 register int dirf;
76 static struct {
77 int ino;
78 char name[16];
79 } entry;
80
81 sgpathp = gpathp;
82 cs = as;
83 while (*cs != '*' && *cs != '?' && *cs != '[') {
84 if (gpathp >= &gpath[PTHSIZ])
85 gpatherr();
86 else if ((*gpathp++ = *cs++) == 0) {
87 if (!globbed)
88 *av++ = cat(as, "");
89 else if (stat(gpath, &stbuff) >= 0) {
90 *av++ = cat(gpath, "");
91 ncoll++;
92 }
93 goto endit;
94 }
95 }
96 gpathp = sgpathp;
97 cs--;
98 while (cs >= as && *cs != '/')
99 cs--;
100 while (as <= cs)
101 if (gpathp >= &gpath[PTHSIZ])
102 gpatherr();
103 else
104 *gpathp++ = *as++;
105 *gpathp = 0;
106 dirf = open(gpath, 0);
107 if (dirf<0)
108 if (globbed)
109 goto endit;
110 else {
111 prs(gpath);
112 panic(": cannot open");
113 }
114 globbed++;
115 cs++;
116 while (read(dirf, &entry, 16) == 16) {
117 if (entry.ino==0)
118 continue;
119 if (match(entry.name, cs)) {
120 *av++ = cat(gpath, entry.name);
121 ncoll++;
122 }
123 }
124 close(dirf);
125endit:
126 gpathp = sgpathp;
127 *gpathp = 0;
128}
129
130toolong()
131{
132 panic("Arg list too long");
133}
134
135gpatherr()
136{
137 prs("Path too long: ");
138 panic(gpath);
139}
140
141match(s, p)
142char *s, *p;
143{
144 register c, sentp;
145
146 if (*s == '.' && *p != '.')
147 return(0);
148 sentp = entp;
149 entp = s;
150 c = amatch(s, p);
151 entp = sentp;
152 return(c);
153}
154
155amatch(as, ap)
156char *as, *ap;
157{
158 register char *s, *p;
159 register scc;
160 int c, cc, ok, lc;
161 char *sgpathp;
162
163 s = as;
164 p = ap;
165nextc:
166 if(scc = *s++ & 0177)
167 if ((scc =& 0177) == 0)
168 scc = 0200;
169 switch (c = *p++) {
170 case '[':
171 ok = 0;
172 lc = 077777;
173 while (cc = *p++) {
174 if (cc == ']') {
175 if (ok)
176 goto nextc;
177 else
178 return(0);
179 } else if (cc == '-') {
180 if (lc <= scc && scc <= *p++)
181 ok++;
182 } else
183 if (scc == (lc = cc))
184 ok++;
185 }
186 panic("missing ]");
187 case '*':
188 if(*p == '\0')
189 return(1);
190 else if (*p == '/') {
191 p++;
192 goto slash;
193 }
194 s--;
195 while(*s)
196 if (amatch(s, p))
197 return(1);
198 else
199 s++;
200 return(0);
201 case '\0':
202 return(scc == '\0');
203 default:
204 if (c == scc)
205 goto nextc;
206 else
207 return(0);
208 case '?':
209 if (scc != '\0')
210 goto nextc;
211 else
212 return(0);
213 case '/':
214 if (scc == '\0') {
215slash:
216 s = entp;
217 sgpathp = gpathp;
218 while (*gpathp = *s++)
219 gpathp++;
220 *gpathp++ = '/';
221 *gpathp = 0;
222 if (stat(gpath, &stbuff) == 0)
223 if ((stbuff[2] & 060000) == 040000)
224 if (*p == 0) {
225 *av++ = cat(gpath, "");
226 ncoll++;
227 } else
228 expand(p);
229 gpathp = sgpathp;
230 *gpathp = 0;
231 }
232 return(0);
233 }
234}
235
236cat(as1, as2)
237char *as1, *as2;
238{
239 register char *s1, *s2;
240
241 s2 = string;
242 s1 = as1;
243 while (*s2++ = (*s1++ & 0177))
244 if (s2 >= &ab[STRSIZ])
245 toolong();
246 s1 = as2;
247 s2--;
248 while (*s2++ = *s1++)
249 if (s2 > &ab[STRSIZ])
250 toolong();
251 s1 = string;
252 string = s2;
253 return(s1);
254}
255
256panic(str)
257{
258 err(str);
259 reset();
260}