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: }

Defined functions

chrcnv defined in line 433; used 2 times
chrdsp defined in line 440; used 3 times
getln defined in line 357; used 4 times
intrser defined in line 418; used 3 times
main defined in line 89; never used

Defined variables

sg defined in line 72; used 13 times
sigenv defined in line 82; used 3 times
sigint defined in line 79; used 4 times
switches defined in line 29; used 3 times
tc defined in line 67; used 2 times
wtuser defined in line 78; used 9 times

Defined macros

BODYSW defined in line 45; never used
CERASE defined in line 24; used 1 times
  • in line 23
CKILL defined in line 21; used 1 times
  • in line 20
ERASE defined in line 69; used 4 times
ERASESW defined in line 30; never used
HELPSW defined in line 50; never used
INTR defined in line 71; used 1 times
KILL defined in line 70; used 4 times
KILLSW defined in line 32; never used
NBODYSW defined in line 47; never used
NPREPSW defined in line 37; never used
NRAPDSW defined in line 42; never used
PREPSW defined in line 35; never used
QUOTE defined in line 19; used 2 times
RAPDSW defined in line 40; never used
Last modified: 1985-11-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1287
Valid CSS Valid XHTML 1.0 Strict