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