|
|
1.1 ! root 1: /* prompter.c - prompting editor front-end */ ! 2: ! 3: #include "../h/mh.h" ! 4: #include <stdio.h> ! 5: #include <errno.h> ! 6: #ifndef SYS5 ! 7: #include <sgtty.h> ! 8: #else SYS5 ! 9: #include <sys/types.h> ! 10: #include <termio.h> ! 11: #include <sys/ioctl.h> ! 12: #endif SYS5 ! 13: #ifdef BSD42 ! 14: #include <setjmp.h> ! 15: #endif BSD42 ! 16: #include <signal.h> ! 17: ! 18: ! 19: #define QUOTE '\\' ! 20: #ifndef CKILL ! 21: #define CKILL '@' ! 22: #endif not CKILL ! 23: #ifndef CERASE ! 24: #define CERASE '#' ! 25: #endif not CERASE ! 26: ! 27: /* */ ! 28: ! 29: static struct swit switches[] = { ! 30: #define ERASESW 0 ! 31: "erase chr", 0, ! 32: #define KILLSW 1 ! 33: "kill chr", 0, ! 34: ! 35: #define PREPSW 2 ! 36: "prepend", 0, ! 37: #define NPREPSW 3 ! 38: "noprepend", 0, ! 39: ! 40: #define RAPDSW 4 ! 41: "rapid", 0, ! 42: #define NRAPDSW 5 ! 43: "norapid", 0, ! 44: ! 45: #define BODYSW 6 ! 46: "body", -4, ! 47: #define NBODYSW 7 ! 48: "nobody", -6, ! 49: ! 50: #define HELPSW 8 ! 51: "help", 4, ! 52: ! 53: NULL, NULL ! 54: }; ! 55: ! 56: /* */ ! 57: ! 58: extern int errno; ! 59: ! 60: ! 61: #ifndef SYS5 ! 62: #define ERASE sg.sg_erase ! 63: #define KILL sg.sg_kill ! 64: static struct sgttyb sg; ! 65: ! 66: #define INTR tc.t_intrc ! 67: static struct tchars tc; ! 68: #else SYS5 ! 69: #define ERASE sg.c_cc[VERASE] ! 70: #define KILL sg.c_cc[VKILL] ! 71: #define INTR sg.c_cc[VINTR] ! 72: static struct termio sg; ! 73: #endif SYS5 ! 74: ! 75: ! 76: int intrser (); ! 77: ! 78: static int wtuser = 0; ! 79: static int sigint = 0; ! 80: ! 81: #ifdef BSD42 ! 82: static jmp_buf sigenv; ! 83: #endif BSD42 ! 84: ! 85: /* */ ! 86: ! 87: /* ARGSUSED */ ! 88: ! 89: main (argc, argv) ! 90: int argc; ! 91: char *argv[]; ! 92: { ! 93: int body = 1, ! 94: prepend = 1, ! 95: rapid = 0, ! 96: fdi, ! 97: fdo, ! 98: i, ! 99: state; ! 100: char *cp, ! 101: *drft = NULL, ! 102: *erasep = NULL, ! 103: *killp = NULL, ! 104: name[NAMESZ], ! 105: field[BUFSIZ], ! 106: buffer[BUFSIZ], ! 107: tmpfil[BUFSIZ], ! 108: **ap, ! 109: *arguments[MAXARGS], ! 110: **argp; ! 111: FILE *in, *out; ! 112: ! 113: invo_name = r1bindex (argv[0], '/'); ! 114: if ((cp = m_find (invo_name)) != NULL) { ! 115: ap = brkstring (cp = getcpy (cp), " ", "\n"); ! 116: ap = copyip (ap, arguments); ! 117: } ! 118: else ! 119: ap = arguments; ! 120: (void) copyip (argv + 1, ap); ! 121: argp = arguments; ! 122: ! 123: /* */ ! 124: ! 125: while (cp = *argp++) ! 126: if (*cp == '-') ! 127: switch (smatch (++cp, switches)) { ! 128: case AMBIGSW: ! 129: ambigsw (cp, switches); ! 130: done (1); ! 131: case UNKWNSW: ! 132: adios (NULLCP, "-%s unknown", cp); ! 133: case HELPSW: ! 134: (void) sprintf (buffer, "%s [switches] file", invo_name); ! 135: help (buffer, switches); ! 136: done (1); ! 137: ! 138: case ERASESW: ! 139: if (!(erasep = *argp++) || *erasep == '-') ! 140: adios (NULLCP, "missing argument to %s", argp[-2]); ! 141: continue; ! 142: case KILLSW: ! 143: if (!(killp = *argp++) || *killp == '-') ! 144: adios (NULLCP, "missing argument to %s", argp[-2]); ! 145: continue; ! 146: ! 147: case PREPSW: ! 148: prepend++; ! 149: continue; ! 150: case NPREPSW: ! 151: prepend = 0; ! 152: continue; ! 153: ! 154: case RAPDSW: ! 155: rapid++; ! 156: continue; ! 157: case NRAPDSW: ! 158: rapid = 0; ! 159: continue; ! 160: ! 161: case BODYSW: ! 162: body++; ! 163: continue; ! 164: case NBODYSW: ! 165: body = 0; ! 166: continue; ! 167: } ! 168: else ! 169: if (!drft) ! 170: drft = cp; ! 171: ! 172: /* */ ! 173: ! 174: if (!drft) ! 175: adios (NULLCP, "usage: %s [switches] file", invo_name); ! 176: if ((in = fopen (drft, "r")) == NULL) ! 177: adios (drft, "unable to open"); ! 178: ! 179: (void) strcpy (tmpfil, m_tmpfil (invo_name)); ! 180: if ((out = fopen (tmpfil, "w")) == NULL) ! 181: adios (tmpfil, "unable to create"); ! 182: (void) chmod (tmpfil, 0600); ! 183: ! 184: if (killp || erasep) { ! 185: #ifndef SYS5 ! 186: int serase, ! 187: skill; ! 188: #else SYS5 ! 189: char serase, ! 190: skill; ! 191: #endif SYS5 ! 192: ! 193: #ifndef SYS5 ! 194: (void) ioctl (0, TIOCGETP, (char *) &sg); ! 195: (void) ioctl (0, TIOCGETC, (char *) &tc); ! 196: #else SYS5 ! 197: (void) ioctl(0, TCGETA, &sg); ! 198: #endif SYS5 ! 199: skill = KILL; ! 200: serase = ERASE; ! 201: KILL = killp ? chrcnv (killp) : skill; ! 202: ERASE = erasep ? chrcnv (erasep) : serase; ! 203: #ifndef SYS5 ! 204: (void) ioctl (0, TIOCSETN, (char *) &sg); ! 205: #else SYS5 ! 206: (void) ioctl(0, TCSETAW, &sg); ! 207: #endif SYS5 ! 208: ! 209: chrdsp ("erase", ERASE); ! 210: chrdsp (", kill", KILL); ! 211: chrdsp (", intr", INTR); ! 212: (void) putchar ('\n'); ! 213: (void) fflush (stdout); ! 214: ! 215: KILL = skill; ! 216: ERASE = serase; ! 217: } ! 218: ! 219: /* */ ! 220: ! 221: sigint = 0; ! 222: setsig (SIGINT, intrser); ! 223: ! 224: for (state = FLD;;) { ! 225: switch (state = m_getfld (state, name, field, sizeof field, in)) { ! 226: case FLD: ! 227: case FLDEOF: ! 228: case FLDPLUS: ! 229: for (cp = field; *cp; cp++) ! 230: if (*cp != ' ' && *cp != '\t') ! 231: break; ! 232: if (*cp++ != '\n' || *cp != NULL) { ! 233: printf ("%s:%s", name, field); ! 234: fprintf (out, "%s:%s", name, field); ! 235: while (state == FLDPLUS) { ! 236: state = ! 237: m_getfld (state, name, field, sizeof field, in); ! 238: printf ("%s", field); ! 239: fprintf (out, "%s", field); ! 240: } ! 241: } ! 242: else { ! 243: printf ("%s: ", name); ! 244: (void) fflush (stdout); ! 245: i = getln (field, sizeof field); ! 246: if (i == -1) { ! 247: abort: ; ! 248: if (killp || erasep) ! 249: #ifndef SYS5 ! 250: (void) ioctl (0, TIOCSETN, (char *) &sg); ! 251: #else SYS5 ! 252: (void) ioctl (0, TCSETA, &sg); ! 253: #endif SYS5 ! 254: (void) unlink (tmpfil); ! 255: done (1); ! 256: } ! 257: if (i != 0 || (field[0] != '\n' && field[0] != NULL)) { ! 258: fprintf (out, "%s:", name); ! 259: do { ! 260: if (field[0] != ' ' && field[0] != '\t') ! 261: (void) putc (' ', out); ! 262: fprintf (out, "%s", field); ! 263: } while (i == 1 ! 264: && (i = getln (field, sizeof field)) >= 0); ! 265: if (i == -1) ! 266: goto abort; ! 267: } ! 268: } ! 269: if (state == FLDEOF) {/* moby hack */ ! 270: fprintf (out, "--------\n"); ! 271: printf ("--------\n"); ! 272: if (!body) ! 273: break; ! 274: goto no_body; ! 275: } ! 276: continue; ! 277: ! 278: case BODY: ! 279: case BODYEOF: ! 280: case FILEEOF: ! 281: fprintf (out, "--------\n"); ! 282: if (field[0] == NULL || !prepend) ! 283: printf ("--------\n"); ! 284: if (field[0]) { ! 285: if (prepend && body) { ! 286: printf ("\n--------Enter initial text\n\n"); ! 287: (void) fflush (stdout); ! 288: for (;;) { ! 289: (void) getln (buffer, sizeof buffer); ! 290: if (buffer[0] == NULL) ! 291: break; ! 292: fprintf (out, "%s", buffer); ! 293: } ! 294: } ! 295: ! 296: do { ! 297: fprintf (out, "%s", field); ! 298: if (!rapid && !sigint) ! 299: printf ("%s", field); ! 300: } while (state == BODY && ! 301: (state = m_getfld (state, name, field, sizeof field, in))); ! 302: if (prepend || !body) ! 303: break; ! 304: else ! 305: printf ("\n--------Enter additional text\n\n"); ! 306: } ! 307: no_body: ; ! 308: (void) fflush (stdout); ! 309: for (;;) { ! 310: (void) getln (field, sizeof field); ! 311: if (field[0] == NULL) ! 312: break; ! 313: fprintf (out, "%s", field); ! 314: } ! 315: break; ! 316: ! 317: default: ! 318: adios (NULLCP, "skeleton is poorly formatted"); ! 319: } ! 320: break; ! 321: } ! 322: ! 323: if (body) ! 324: printf ("--------\n"); ! 325: (void) fflush (stdout); ! 326: ! 327: (void) fclose (in); ! 328: (void) fclose (out); ! 329: ! 330: (void) signal (SIGINT, SIG_IGN); ! 331: ! 332: /* */ ! 333: ! 334: if (killp || erasep) ! 335: #ifndef SYS5 ! 336: (void) ioctl (0, TIOCSETN, (char *) &sg); ! 337: #else SYS5 ! 338: (void) ioctl (0, TCSETAW, &sg); ! 339: #endif SYS5 ! 340: ! 341: if ((fdi = open (tmpfil, 0)) == NOTOK) ! 342: adios (tmpfil, "unable to re-open"); ! 343: if ((fdo = creat (drft, m_gmprot ())) == NOTOK) ! 344: adios (drft, "unable to write"); ! 345: cpydata (fdi, fdo, tmpfil, drft); ! 346: (void) close (fdi); ! 347: (void) close (fdo); ! 348: (void) unlink (tmpfil); ! 349: ! 350: m_update (); ! 351: ! 352: done (0); ! 353: } ! 354: ! 355: /* */ ! 356: ! 357: getln (buffer, n) ! 358: register char *buffer; ! 359: register int n; ! 360: { ! 361: int c; ! 362: char *cp; ! 363: ! 364: cp = buffer; ! 365: *cp = NULL; ! 366: ! 367: #ifndef BSD42 ! 368: wtuser = 1; ! 369: #else BSD42 ! 370: switch (setjmp (sigenv)) { ! 371: case OK: ! 372: wtuser = 1; ! 373: break; ! 374: ! 375: case DONE: ! 376: wtuser = 0; ! 377: return 0; ! 378: ! 379: default: ! 380: wtuser = 0; ! 381: return NOTOK; ! 382: } ! 383: #endif BSD42 ! 384: ! 385: for (;;) ! 386: switch (c = getchar ()) { ! 387: case EOF: ! 388: #ifndef BSD42 ! 389: wtuser = 0; ! 390: return (errno != EINTR ? 0 : NOTOK); ! 391: #else BSD42 ! 392: clearerr (stdin); ! 393: longjmp (sigenv, DONE); ! 394: #endif BSD42 ! 395: ! 396: case '\n': ! 397: if (cp[-1] == QUOTE) { ! 398: cp[-1] = c; ! 399: wtuser = 0; ! 400: return 1; ! 401: } ! 402: *cp++ = c; ! 403: *cp = NULL; ! 404: wtuser = 0; ! 405: return 0; ! 406: ! 407: default: ! 408: if (cp < buffer + n) ! 409: *cp++ = c; ! 410: *cp = NULL; ! 411: } ! 412: } ! 413: ! 414: /* */ ! 415: ! 416: /* ARGSUSED */ ! 417: ! 418: static int intrser (i) ! 419: int i; ! 420: { ! 421: #ifndef BSD42 ! 422: (void) signal (SIGINT, intrser); ! 423: if (!wtuser) ! 424: sigint++; ! 425: #else BSD42 ! 426: if (wtuser) ! 427: longjmp (sigenv, NOTOK); ! 428: sigint++; ! 429: #endif BSD42 ! 430: } ! 431: ! 432: ! 433: chrcnv (cp) ! 434: register char *cp; ! 435: { ! 436: return (*cp != QUOTE ? *cp : m_atoi (++cp)); ! 437: } ! 438: ! 439: ! 440: chrdsp (s, c) ! 441: char *s, ! 442: c; ! 443: { ! 444: printf ("%s ", s); ! 445: if (c < ' ' || c == 0177) ! 446: printf ("^%c", c ^ 0100); ! 447: else ! 448: printf ("%c", c); ! 449: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.