Commit | Line | Data |
---|---|---|
a0216d6a BJ |
1 | # |
2 | # include <stdio.h> | |
3 | # include <ctype.h> | |
4 | # include <signal.h> | |
5 | /* C command */ | |
6 | ||
7 | # define SBSIZE 10000 | |
8 | # define MAXINC 10 | |
9 | # define MAXFIL 100 | |
10 | # define MAXLIB 100 | |
11 | # define MAXOPT 100 | |
12 | char tmp0[30]; | |
13 | char *tmp1; | |
14 | char *tmp2; | |
15 | char *tmp3; | |
16 | char *tmp4; | |
17 | char *tmp5; | |
18 | char *outfile; | |
19 | char *copy(),*setsuf(); | |
20 | # define CHSPACE 1000 | |
21 | char ts[CHSPACE+50]; | |
22 | char *tsa = ts; | |
23 | char *tsp = ts; | |
24 | char *av[50]; | |
25 | char *clist[MAXFIL]; | |
26 | char *llist[MAXLIB]; | |
27 | char *alist[20]; | |
28 | int Wflag; | |
29 | int dflag; | |
30 | int pflag; | |
31 | int sflag; | |
32 | int cflag; | |
33 | int eflag; | |
34 | int gflag; | |
35 | int exflag; | |
36 | int oflag; | |
37 | int proflag; | |
38 | int noflflag; | |
39 | int exfail; | |
40 | char *chpass ; | |
41 | char *npassname ; | |
42 | char pass0[40] = "/lib/ccom"; | |
43 | char pass2[20] = "/lib/c2"; | |
44 | char passp[20] = "/lib/cpp"; | |
45 | char *pref = "/lib/crt0.o"; | |
46 | ||
47 | main(argc, argv) | |
48 | char *argv[]; { | |
49 | char *t; | |
50 | char *savetsp; | |
51 | char *assource; | |
52 | char **pv, *ptemp[MAXOPT], **pvt; | |
53 | int nc, nl, i, j, c, f20, nxo, na; | |
54 | int idexit(); | |
55 | ||
56 | i = nc = nl = f20 = nxo = 0; | |
57 | pv = ptemp; | |
58 | while(++i < argc) { | |
59 | if(*argv[i] == '-') switch (argv[i][1]) { | |
60 | default: | |
61 | goto passa; | |
62 | case 'S': | |
63 | sflag++; | |
64 | cflag++; | |
65 | break; | |
66 | case 'o': | |
67 | if (++i < argc) { | |
68 | char t; | |
69 | outfile = argv[i]; | |
70 | if ((t=getsuf(outfile))=='c'||t=='o') { | |
71 | error("Would overwrite %s", outfile); | |
72 | exit(8); | |
73 | } | |
74 | } | |
75 | break; | |
76 | case 'O': | |
77 | oflag++; | |
78 | break; | |
79 | case 'p': | |
80 | proflag++; | |
81 | break; | |
82 | case 'g': | |
83 | gflag++; | |
84 | break; | |
85 | case 'W': /* deprecated */ | |
86 | case 'w': | |
87 | Wflag++; | |
88 | break; | |
89 | case 'E': | |
90 | exflag++; | |
91 | case 'P': | |
92 | pflag++; | |
93 | if (argv[i][1]=='P') | |
94 | fprintf(stderr, "(Warning): -P option obsolete\n"); | |
95 | *pv++ = argv[i]; | |
96 | case 'c': | |
97 | cflag++; | |
98 | break; | |
99 | ||
100 | case 'f': | |
101 | noflflag++; | |
102 | if (npassname || chpass) | |
103 | error("-f overwrites earlier option",0); | |
104 | npassname = "/lib/f"; | |
105 | chpass = "12"; | |
106 | break; | |
107 | ||
108 | case '2': | |
109 | if(argv[i][2] == '\0') | |
110 | pref = "/lib/crt2.o"; | |
111 | else { | |
112 | pref = "/lib/crt20.o"; | |
113 | f20 = 1; | |
114 | } | |
115 | break; | |
116 | case 'D': | |
117 | case 'I': | |
118 | case 'U': | |
119 | case 'C': | |
120 | *pv++ = argv[i]; | |
121 | if (pv >= ptemp+MAXOPT) | |
122 | { | |
123 | error("Too many DIUC options", 0); | |
124 | --pv; | |
125 | } | |
126 | break; | |
127 | case 't': | |
128 | if (chpass) | |
129 | error("-t overwrites earlier option",0); | |
130 | chpass = argv[i]+2; | |
131 | if (chpass[0]==0) | |
132 | chpass = "012p"; | |
133 | break; | |
134 | ||
135 | case 'B': | |
136 | if (npassname) | |
137 | error("-B overwrites earlier option", 0); | |
138 | npassname = argv[i]+2; | |
139 | if (npassname[0]==0) | |
140 | npassname = "/usr/c/o"; | |
141 | break; | |
142 | ||
143 | case 'd': | |
144 | dflag++; | |
145 | strcpyn(alist, argv[i], 19); | |
146 | break; | |
147 | } else { | |
148 | passa: | |
149 | t = argv[i]; | |
150 | if((c=getsuf(t))=='c' || c=='s'|| exflag) { | |
151 | clist[nc++] = t; | |
152 | if (nc>=MAXFIL) | |
153 | { | |
154 | error("Too many source files",0); | |
155 | exit(1); | |
156 | } | |
157 | t = setsuf(t, 'o'); | |
158 | } | |
159 | if (nodup(llist, t)) { | |
160 | llist[nl++] = t; | |
161 | if (nl >= MAXLIB) | |
162 | { | |
163 | error("Too many object/library files",0); | |
164 | exit(1); | |
165 | } | |
166 | if (getsuf(t)=='o') | |
167 | nxo++; | |
168 | } | |
169 | } | |
170 | } | |
171 | if (gflag) oflag = 0; | |
172 | if (npassname && chpass ==0) | |
173 | chpass = "012p"; | |
174 | if (chpass && npassname==0) | |
175 | npassname = "/usr/c/"; | |
176 | if (chpass) | |
177 | for (t=chpass; *t; t++) | |
178 | { | |
179 | switch (*t) | |
180 | { | |
181 | case '0': | |
182 | strcpy (pass0, npassname); | |
183 | strcat (pass0, "ccom"); | |
184 | continue; | |
185 | case '2': | |
186 | strcpy (pass2, npassname); | |
187 | strcat (pass2, "c2"); | |
188 | continue; | |
189 | case 'p': | |
190 | strcpy (passp, npassname); | |
191 | strcat (passp, "cpp"); | |
192 | continue; | |
193 | } | |
194 | } | |
195 | if (noflflag) | |
196 | pref = proflag ? "/lib/fmcrt0.o" : "/lib/fcrt0.o"; | |
197 | else if (proflag) | |
198 | pref = "/lib/mcrt0.o"; | |
199 | if(nc==0) | |
200 | goto nocom; | |
201 | if (pflag==0) { | |
202 | FILE *c; | |
203 | sprintf(tmp0,"/tmp/ctm%05.5da",getpid()); | |
204 | while((c=fopen(tmp0, "r")) != NULL) { | |
205 | fclose(c); | |
206 | tmp0[9]++; | |
207 | } | |
208 | while((creat(tmp0, 0400))<0) | |
209 | tmp0[9]++; | |
210 | } | |
211 | if (signal(SIGINT, SIG_IGN) != SIG_IGN) /* interrupt */ | |
212 | signal(SIGINT, idexit); | |
213 | if (signal(SIGTERM, SIG_IGN) != SIG_IGN) /* terminate */ | |
214 | signal(SIGTERM, idexit); | |
215 | (tmp1 = copy(tmp0))[13] = '1'; | |
216 | (tmp2 = copy(tmp0))[13] = '2'; | |
217 | (tmp3 = copy(tmp0))[13] = '3'; | |
218 | if (oflag) | |
219 | (tmp5 = copy(tmp0))[13] = '5'; | |
220 | if (pflag==0) | |
221 | (tmp4 = copy(tmp0))[13] = '4'; | |
222 | pvt = pv; | |
223 | for (i=0; i<nc; i++) { | |
224 | if (nc>1) { | |
225 | printf("%s:\n", clist[i]); | |
226 | fflush(stdout); | |
227 | } | |
228 | if (getsuf(clist[i])=='s') { | |
229 | assource = clist[i]; | |
230 | goto assemble; | |
231 | } else | |
232 | assource = tmp3; | |
233 | if (pflag) | |
234 | tmp4 = setsuf(clist[i], 'i'); | |
235 | savetsp = tsp; | |
236 | av[0] = "cpp"; | |
237 | av[1] = clist[i]; | |
238 | av[2] = exflag ? "-" : tmp4; | |
239 | na = 3; | |
240 | for(pv=ptemp; pv <pvt; pv++) | |
241 | av[na++] = *pv; | |
242 | av[na++]=0; | |
243 | if (callsys(passp, av)) | |
244 | {exfail++; eflag++;} | |
245 | av[1] =tmp4; | |
246 | tsp = savetsp; | |
247 | av[0]= "ccom"; | |
248 | if (pflag || exfail) | |
249 | { | |
250 | cflag++; | |
251 | continue; | |
252 | } | |
253 | if(sflag) | |
254 | assource = tmp3 = setsuf(clist[i], 's'); | |
255 | av[2] = tmp3; | |
256 | if(oflag) | |
257 | av[2] = tmp5; | |
258 | if (proflag) { | |
259 | av[3] = "-XP"; | |
260 | av[4] = 0; | |
261 | } else | |
262 | av[3] = 0; | |
263 | if (gflag) { | |
264 | int i; | |
265 | ||
266 | i = av[3] ? 4 : 3; | |
267 | av[i++] = "-Xg"; | |
268 | av[i] = 0; | |
269 | } | |
270 | if (Wflag) { | |
271 | int i; | |
272 | ||
273 | for (i = 3; i < 10 && av[i] != 0; i++) | |
274 | ; | |
275 | av[i] = "-W"; | |
276 | av[++i] = 0; | |
277 | } | |
278 | ||
279 | if (callsys(pass0, av)) { | |
280 | cflag++; | |
281 | eflag++; | |
282 | continue; | |
283 | } | |
284 | if (oflag) { | |
285 | av[0] = "c2"; | |
286 | av[1] = tmp5; | |
287 | av[2] = tmp3; | |
288 | av[3] = 0; | |
289 | if (callsys(pass2, av)) { | |
290 | unlink(tmp3); | |
291 | tmp3 = assource = tmp5; | |
292 | } else | |
293 | unlink(tmp5); | |
294 | } | |
295 | if (sflag) | |
296 | continue; | |
297 | assemble: | |
298 | av[0] = "as"; | |
299 | av[1] = "-o"; | |
300 | av[2] = setsuf(clist[i], 'o'); | |
301 | av[3] = assource; | |
302 | if (dflag) { | |
303 | av[4] = alist; | |
304 | av[5] = 0; | |
305 | } else | |
306 | av[4] = 0; | |
307 | cunlink(tmp1); | |
308 | cunlink(tmp2); | |
309 | cunlink(tmp4); | |
310 | if (callsys("/bin/as", av) > 1) { | |
311 | cflag++; | |
312 | eflag++; | |
313 | continue; | |
314 | } | |
315 | } | |
316 | nocom: | |
317 | if (cflag==0 && nl!=0) { | |
318 | i = 0; | |
319 | av[0] = "ld"; | |
320 | av[1] = "-X"; | |
321 | av[2] = pref; | |
322 | j = 3; | |
323 | if (outfile) { | |
324 | av[j++] = "-o"; | |
325 | av[j++] = outfile; | |
326 | } | |
327 | while(i<nl) | |
328 | av[j++] = llist[i++]; | |
329 | if (gflag) | |
330 | av[j++] = "-lg"; | |
331 | if(f20) | |
332 | av[j++] = "-l2"; | |
333 | else { | |
334 | av[j++] = "/lib/libc.a"; | |
335 | av[j++] = "-l"; | |
336 | } | |
337 | av[j++] = 0; | |
338 | eflag |= callsys("/bin/ld", av); | |
339 | if (nc==1 && nxo==1 && eflag==0) | |
340 | cunlink(setsuf(clist[0], 'o')); | |
341 | } | |
342 | dexit(); | |
343 | } | |
344 | ||
345 | idexit() | |
346 | { | |
347 | eflag = 100; | |
348 | dexit(); | |
349 | } | |
350 | ||
351 | dexit() | |
352 | { | |
353 | if (!pflag) { | |
354 | cunlink(tmp1); | |
355 | cunlink(tmp2); | |
356 | if (sflag==0) | |
357 | cunlink(tmp3); | |
358 | cunlink(tmp4); | |
359 | cunlink(tmp5); | |
360 | cunlink(tmp0); | |
361 | } | |
362 | exit(eflag); | |
363 | } | |
364 | ||
365 | error(s, x) | |
366 | { | |
367 | fprintf(exflag?stderr:stdout , s, x); | |
368 | putc('\n', exflag? stderr : stdout); | |
369 | exfail++; | |
370 | cflag++; | |
371 | eflag++; | |
372 | } | |
373 | ||
374 | ||
375 | ||
376 | ||
377 | getsuf(as) | |
378 | char as[]; | |
379 | { | |
380 | register int c; | |
381 | register char *s; | |
382 | register int t; | |
383 | ||
384 | s = as; | |
385 | c = 0; | |
386 | while(t = *s++) | |
387 | if (t=='/') | |
388 | c = 0; | |
389 | else | |
390 | c++; | |
391 | s -= 3; | |
392 | if (c<=14 && c>2 && *s++=='.') | |
393 | return(*s); | |
394 | return(0); | |
395 | } | |
396 | ||
397 | char * | |
398 | setsuf(as, ch) | |
399 | char as[]; | |
400 | { | |
401 | register char *s, *s1; | |
402 | ||
403 | s = s1 = copy(as); | |
404 | while(*s) | |
405 | if (*s++ == '/') | |
406 | s1 = s; | |
407 | s[-1] = ch; | |
408 | return(s1); | |
409 | } | |
410 | ||
411 | callsys(f, v) | |
412 | char f[], *v[]; { | |
413 | int t, status; | |
414 | ||
415 | if ((t=vfork())==0) { | |
416 | execv(f, v); | |
417 | printf("Can't find %s\n", f); | |
418 | fflush(stdout); | |
419 | _exit(100); | |
420 | } else | |
421 | if (t == -1) { | |
422 | printf("Try again\n"); | |
423 | return(100); | |
424 | } | |
425 | while(t!=wait(&status)); | |
426 | if ((t=(status&0377)) != 0 && t!=14) { | |
427 | if (t!=2) /* interrupt */ | |
428 | { | |
429 | printf("Fatal error in %s\n", f); | |
430 | eflag = 8; | |
431 | } | |
432 | dexit(); | |
433 | } | |
434 | return((status>>8) & 0377); | |
435 | } | |
436 | ||
437 | char * | |
438 | copy(as) | |
439 | char as[]; | |
440 | { | |
441 | register char *otsp, *s; | |
442 | int i; | |
443 | ||
444 | otsp = tsp; | |
445 | s = as; | |
446 | while(*tsp++ = *s++); | |
447 | if (tsp >tsa+CHSPACE) | |
448 | { | |
449 | tsp = tsa = i = calloc(CHSPACE+50,1); | |
450 | if (i== -1){ | |
451 | error("no space for file names"); | |
452 | dexit(8); | |
453 | } | |
454 | } | |
455 | return(otsp); | |
456 | } | |
457 | ||
458 | nodup(l, os) | |
459 | char **l, *os; | |
460 | { | |
461 | register char *t, *s; | |
462 | register int c; | |
463 | ||
464 | s = os; | |
465 | if (getsuf(s) != 'o') | |
466 | return(1); | |
467 | while(t = *l++) { | |
468 | while(c = *s++) | |
469 | if (c != *t++) | |
470 | break; | |
471 | if (*t=='\0' && c=='\0') | |
472 | return(0); | |
473 | s = os; | |
474 | } | |
475 | return(1); | |
476 | } | |
477 | ||
478 | cunlink(f) | |
479 | char *f; | |
480 | { | |
481 | if (f==0) | |
482 | return(0); | |
483 | return(unlink(f)); | |
484 | } |