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