|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)copy.c 4.2 (Berkeley) 4/25/83";
3: #endif not lint
4:
5: #include "stdio.h"
6: #include "signal.h"
7: #include "lrnref.h"
8:
9: char togo[50];
10: char last[100];
11: char logf[100];
12: char subdir[100];
13: extern char *ctime();
14: extern int review;
15: int noclobber;
16:
17: copy(prompt, fin)
18: int prompt;
19: FILE *fin;
20: {
21: FILE *fout, *f;
22: char s[100], t[100], s1[100], nm[30];
23: char *r, *tod, c;
24: int *p, tv[2];
25: extern int intrpt(), *action();
26: extern char *wordb();
27: int nmatch = 0;
28: long mark;
29:
30: if (subdir[0]==0)
31: sprintf(subdir, "%s/%s", direct, sname);
32: for (;;) {
33: if (pgets(s, prompt, fin) == 0)
1.1.1.2 ! root 34: if (fin == stdin) {
1.1 root 35: fprintf(stderr, "Type \"bye\" if you want to leave learn.\n");
36: fflush(stderr);
37: continue;
1.1.1.2 ! root 38: }
1.1 root 39: trim(s); /* trim newline */
40: /* change the sequence %s to lesson directory */
41: /* if needed */
42: for (r = s; *r; r++)
43: if (*r == '%') {
44: sprintf(s1, s, subdir, subdir, subdir);
45: strcpy(s, s1);
46: break;
47: }
48: r = wordb(s, t); /* t = first token, r = rest */
49: p = action(t); /* p = token class */
50: if (*p == ONCE) { /* some actions done only once per script */
51: if (wrong && !review) { /* we are on 2nd time */
52: scopy(fin, NULL);
53: continue;
54: }
55: strcpy(s, r);
56: r = wordb(s, t);
57: p = action(t);
58: }
59: if (p == 0) {
60: if (comfile >= 0) { /* if #pipe in effect ... */
61: write(comfile, s, strlen(s));
62: write(comfile, "\n", 1);
63: }
64: else { /* else must be UNIX command ... */
65: signal(SIGINT, SIG_IGN);
66: status = mysys(s);
67: signal(SIGINT, intrpt);
68: }
69: if (incopy) {
70: fprintf(incopy, "%s\n", s);
71: strcpy(last, s);
72: }
73: continue;
74: }
75: switch (*p) {
76: case READY:
77: if (incopy && r) {
78: fprintf(incopy, "%s\n", r);
79: strcpy(last, r);
80: }
81: return;
82: case PRINT:
83: if (wrong)
84: scopy(fin, NULL); /* don't repeat message */
85: else if (r)
86: list(r);
87: else
88: scopy(fin, stdout);
89: break;
90: case XYZZY:
91: mark = ftell(scrin);
92: if (r)
93: rewind(scrin);
94: while ((int)(c=fgetc(scrin)) != EOF)
95: putchar(c);
96: fflush(stdout);
97: fseek(scrin, mark, 0);
98: break;
99: case NOP:
100: break;
101: case MATCH:
102: if (nmatch > 0) /* we have already passed */
103: scopy(fin, NULL);
104: else if ((status = strcmp(r, last)) == 0) { /* did we pass this time? */
105: nmatch++;
106: scopy(fin, stdout);
107: } else
108: scopy(fin, NULL);
109: break;
110: case BAD:
111: if (strcmp(r, last) == 0) {
112: scopy(fin, stdout);
113: } else
114: scopy(fin, NULL);
115: break;
116: case SUCCEED:
117: scopy(fin, (status == 0) ? stdout : NULL);
118: break;
119: case FAIL:
120: scopy(fin, (status != 0) ? stdout : NULL);
121: break;
122: case CREATE:
123: if (noclobber)
124: fout = NULL;
125: else
126: fout = fopen(r, "w");
127: scopy(fin, fout);
128: if (!noclobber)
129: fclose(fout);
130: break;
131: case CMP:
132: status = cmp(r); /* contains two file names */
133: break;
134: case MV:
135: sprintf(nm, "%s/L%s.%s", subdir, todo, r);
136: fcopy(r, nm);
137: break;
138: case USER:
139: case NEXT:
140: if (noclobber)
141: noclobber = 0;
142: more = 1;
143: return;
144: case AGAIN:
145: review = 0;
146: if (!r) {
147: r = todo;
148: noclobber = 1;
149: review = 1;
150: }
151: again = 1;
152: strcpy(togo, r);
153: unhook();
154: return;
155: case SKIP:
156: skip = 1;
157: unhook();
158: return;
159: case COPYIN:
160: incopy = fopen(".copy", "w");
161: break;
162: case UNCOPIN:
163: fclose(incopy);
164: incopy = NULL;
165: break;
166: case COPYOUT:
167: teed = maktee();
168: break;
169: case UNCOPOUT:
170: untee();
171: teed = 0;
172: break;
173: case PIPE:
174: comfile = makpipe();
175: break;
176: case UNPIPE:
177: close(comfile);
178: wait(0);
179: comfile = -1;
180: break;
181: case YES:
182: case NO:
183: if (incopy) {
184: fprintf(incopy, "%s\n", s);
185: strcpy(last, s);
186: }
187: return;
188: case WHERE:
189: printf("You are in lesson %s of \"%s\" with a speed rating of %d.\n", todo, sname, speed);
190: printf("You have completed %d out of a possible %d lessons.\n", sequence-1, total);
191: if (r)
192: tellwhich();
193: fflush(stdout);
194: break;
195: case BYE:
196: more=0;
197: return;
198: case CHDIR:
199: printf("cd not allowed\n");
200: fflush(stdout);
201: break;
202: case LEARN:
203: printf("You are already in learn.\n");
204: fflush(stdout);
205: break;
206: case LOG:
207: if (!logging)
208: break;
209: if (logf[0] == 0)
210: sprintf(logf, "%s/log/%s", direct, sname);
211: f = fopen((r ? r : logf), "a");
212: if (f == NULL)
213: break;
214: time(tv);
215: tod = ctime(tv);
216: tod[24] = 0;
217: fprintf(f, "%s L%-6s %s %2d %s\n", tod,
218: todo, status? "fail" : "pass", speed, pwline);
219: fclose(f);
220: break;
221: }
222: }
223: }
224:
225: pgets(s, prompt, f)
226: char *s;
227: int prompt;
228: FILE *f;
229: {
230: if (prompt) {
231: if (comfile < 0)
232: fputs("% ", stdout);
233: fflush(stdout);
234: }
235: if (fgets(s, 100,f))
236: return(1);
1.1.1.2 ! root 237: if (f == stdin) rewind(f);
! 238: return(0);
1.1 root 239: }
240:
241: trim(s)
242: char *s;
243: {
244: while (*s)
245: s++;
246: if (*--s == '\n')
247: *s=0;
248: }
249:
250: scopy(fi, fo) /* copy fi to fo until a line with #
251: * sequence "#\n" means a line not ending with \n
252: * control-M's are filtered out */
253: FILE *fi, *fo;
254: {
255: int c;
256:
257: while ((c = getc(fi)) != '#' && c != EOF) {
258: do {
259: if (c == '#') {
260: c = getc(fi);
261: if (c == '\n')
262: break;
263: if (c == EOF) {
264: fflush(fo);
265: return;
266: }
267: if (fo != NULL)
268: putc('#', fo);
269: }
270: if (c == '\r')
271: break;
272: if (fo != NULL)
273: putc(c, fo);
274: if (c == '\n')
275: break;
276: } while ((c = getc(fi)) != EOF);
277: }
278: if (c == '#')
279: ungetc(c, fi);
280: fflush(fo);
281: }
282:
283: cmp(r) /* compare two files for status; #cmp f1 f2 [ firstnlinesonly ] */
284: char *r;
285: {
286: char *s, *h;
287: FILE *f1, *f2;
288: int c1, c2, stat, n;
289:
290: for (s = r; *s != ' ' && *s != '\0'; s++)
291: ;
292: *s++ = 0; /* r contains file 1 */
293: while (*s == ' ')
294: s++;
295: for (h = s; *h != ' ' && *h != '\0'; h++)
296: ;
297: if (*h) {
298: *h++ = 0;
299: while (*h == ' ')
300: h++;
301: n = atoi(h);
302: }
303: else
304: n = 077777;
305: f1 = fopen(r, "r");
306: f2 = fopen(s, "r");
307: if (f1 == NULL || f2 == NULL)
308: return(1); /* failure */
309: stat = 0;
310: for (;;) {
311: c1 = getc(f1);
312: c2 = getc(f2);
313: if (c1 != c2) {
314: stat = 1;
315: break;
316: }
317: if (*h && c1 == '\n')
318: if (--n)
319: break;
320: if (c1 == EOF || c2 == EOF)
321: break;
322: }
323: fclose(f1);
324: fclose(f2);
325: return(stat);
326: }
327:
328: char *
329: wordb(s, t) /* in s, t is prefix; return tail */
330: char *s, *t;
331: {
332: int c;
333:
334: while (c = *s++) {
335: if (c == ' ' || c == '\t')
336: break;
337: *t++ = c;
338: }
339: *t = 0;
340: while (*s == ' ' || *s == '\t')
341: s++;
342: return(c ? s : NULL);
343: }
344:
345: unhook()
346: {
347: if (incopy) {
348: fclose(incopy);
349: incopy = NULL;
350: }
351: if (comfile >= 0) {
352: close(comfile);
353: wait(0);
354: comfile = -1;
355: }
356: if (teed) {
357: teed = 0;
358: untee();
359: }
360: fclose(scrin);
361: scrin = NULL;
362: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.