-
/*
- * prompter.c -- simple prompting editor front-end
- *
- * $Id$
- *
- * This code is Copyright (c) 2002, by the authors of nmh. See the
- * COPYRIGHT file in the root directory of the nmh distribution for
- * complete copyright information.
- */
+** prompter.c -- simple prompting editor front-end
+**
+** This code is Copyright (c) 2002, by the authors of nmh. See the
+** COPYRIGHT file in the root directory of the nmh distribution for
+** complete copyright information.
+*/
#include <h/mh.h>
#include <fcntl.h>
# endif
#endif
-#define QUOTE '\\'
+#define QUOTE '\\'
-#ifndef CKILL
+#ifndef CKILL
# define CKILL '@'
#endif
-#ifndef CERASE
+#ifndef CERASE
# define CERASE '#'
#endif
static struct swit switches[] = {
-#define ERASESW 0
- { "erase chr", 0 },
-#define KILLSW 1
- { "kill chr", 0 },
-#define PREPSW 2
- { "prepend", 0 },
-#define NPREPSW 3
- { "noprepend", 0 },
-#define RAPDSW 4
- { "rapid", 0 },
-#define NRAPDSW 5
- { "norapid", 0 },
-#define BODYSW 6
- { "body", -4 },
-#define NBODYSW 7
- { "nobody", -6 },
-#define DOTSW 8
- { "doteof", 0 },
-#define NDOTSW 9
- { "nodoteof", 0 },
+#define ERASESW 0
+ { "erase chr", 0 },
+#define KILLSW 1
+ { "kill chr", 0 },
+#define PREPSW 2
+ { "prepend", 0 },
+#define NPREPSW 3
+ { "noprepend", 0 },
+#define RAPDSW 4
+ { "rapid", 0 },
+#define NRAPDSW 5
+ { "norapid", 0 },
+#define BODYSW 6
+ { "body", -4 },
+#define NBODYSW 7
+ { "nobody", -6 },
+#define DOTSW 8
+ { "doteof", 0 },
+#define NDOTSW 9
+ { "nodoteof", 0 },
#define VERSIONSW 10
- { "version", 0 },
-#define HELPSW 11
- { "help", 0 },
- { NULL, 0 }
+ { "version", 0 },
+#define HELPSW 11
+ { "help", 0 },
+ { NULL, 0 }
};
static jmp_buf sigenv;
/*
- * prototypes
- */
-int getln (char *, int);
-static int chrcnv (char *);
-static void chrdsp (char *, char);
-static RETSIGTYPE intrser (int);
+** prototypes
+*/
+int getln(char *, int);
+static int chrcnv(char *);
+static void chrdsp(char *, char);
+static RETSIGTYPE intrser(int);
int
-main (int argc, char **argv)
+main(int argc, char **argv)
{
- int body = 1, prepend = 1, rapid = 0;
- int doteof = 0, fdi, fdo, i, state;
- char *cp, *drft = NULL, *erasep = NULL;
- char *killp = NULL, name[NAMESZ], field[BUFSIZ];
- char buffer[BUFSIZ], tmpfil[BUFSIZ];
- char **arguments, **argp;
- FILE *in, *out;
+ int body = 1, prepend = 1, rapid = 0;
+ int doteof = 0, fdi, fdo, i, state;
+ char *cp, *drft = NULL, *erasep = NULL;
+ char *killp = NULL, name[NAMESZ], field[BUFSIZ];
+ char buffer[BUFSIZ], tmpfil[BUFSIZ];
+ char **arguments, **argp;
+ FILE *in, *out;
+ char *tfile = NULL;
#ifdef LOCALE
- setlocale(LC_ALL, "");
+ setlocale(LC_ALL, "");
#endif
- invo_name = r1bindex (argv[0], '/');
-
- /* read user profile/context */
- context_read();
-
- arguments = getarguments (invo_name, argc, argv, 1);
- argp = arguments;
-
- while ((cp = *argp++))
- if (*cp == '-') {
- switch (smatch (++cp, switches)) {
- case AMBIGSW:
- ambigsw (cp, switches);
- done (1);
- case UNKWNSW:
- adios (NULL, "-%s unknown", cp);
-
- case HELPSW:
- snprintf (buffer, sizeof(buffer), "%s [switches] file",
- invo_name);
- print_help (buffer, switches, 1);
- done (1);
- case VERSIONSW:
- print_version(invo_name);
- done (1);
-
- case ERASESW:
- if (!(erasep = *argp++) || *erasep == '-')
- adios (NULL, "missing argument to %s", argp[-2]);
- continue;
- case KILLSW:
- if (!(killp = *argp++) || *killp == '-')
- adios (NULL, "missing argument to %s", argp[-2]);
- continue;
-
- case PREPSW:
- prepend++;
- continue;
- case NPREPSW:
- prepend = 0;
- continue;
-
- case RAPDSW:
- rapid++;
- continue;
- case NRAPDSW:
- rapid = 0;
- continue;
-
- case BODYSW:
- body++;
- continue;
- case NBODYSW:
- body = 0;
- continue;
-
- case DOTSW:
- doteof++;
- continue;
- case NDOTSW:
- doteof = 0;
- continue;
- }
- } else {
- if (!drft)
- drft = cp;
- }
+ invo_name = mhbasename(argv[0]);
+
+ /* read user profile/context */
+ context_read();
+
+ arguments = getarguments(invo_name, argc, argv, 1);
+ argp = arguments;
+
+ while ((cp = *argp++))
+ if (*cp == '-') {
+ switch (smatch(++cp, switches)) {
+ case AMBIGSW:
+ ambigsw(cp, switches);
+ done(1);
+ case UNKWNSW:
+ adios(NULL, "-%s unknown", cp);
+
+ case HELPSW:
+ snprintf(buffer, sizeof(buffer),
+ "%s [switches] file",
+ invo_name);
+ print_help(buffer, switches, 1);
+ done(1);
+ case VERSIONSW:
+ print_version(invo_name);
+ done(1);
+
+ case ERASESW:
+ if (!(erasep = *argp++) || *erasep == '-')
+ adios(NULL, "missing argument to %s",
+ argp[-2]);
+ continue;
+ case KILLSW:
+ if (!(killp = *argp++) || *killp == '-')
+ adios(NULL, "missing argument to %s",
+ argp[-2]);
+ continue;
+
+ case PREPSW:
+ prepend++;
+ continue;
+ case NPREPSW:
+ prepend = 0;
+ continue;
+
+ case RAPDSW:
+ rapid++;
+ continue;
+ case NRAPDSW:
+ rapid = 0;
+ continue;
+
+ case BODYSW:
+ body++;
+ continue;
+ case NBODYSW:
+ body = 0;
+ continue;
+
+ case DOTSW:
+ doteof++;
+ continue;
+ case NDOTSW:
+ doteof = 0;
+ continue;
+ }
+ } else if (!drft) {
+ drft = cp;
+ }
- if (!drft)
- adios (NULL, "usage: %s [switches] file", invo_name);
- if ((in = fopen (drft, "r")) == NULL)
- adios (drft, "unable to open");
+ if (!drft)
+ adios(NULL, "usage: %s [switches] file", invo_name);
+ if ((in = fopen(drft, "r")) == NULL)
+ adios(drft, "unable to open");
- strncpy (tmpfil, m_tmpfil (invo_name), sizeof(tmpfil));
- if ((out = fopen (tmpfil, "w")) == NULL)
- adios (tmpfil, "unable to create");
- chmod (tmpfil, 0600);
+ tfile = m_mktemp2(NULL, invo_name, NULL, &out);
+ if (tfile == NULL)
+ adios("prompter", "unable to create temporary file");
+ chmod(tmpfil, 0600);
+ strncpy(tmpfil, tfile, sizeof(tmpfil));
- /*
- * Are we changing the kill or erase character?
- */
- if (killp || erasep) {
+ /*
+ ** Are we changing the kill or erase character?
+ */
+ if (killp || erasep) {
#ifdef HAVE_TERMIOS_H
- cc_t save_erase, save_kill;
+ cc_t save_erase, save_kill;
#else
- int save_erase, save_kill;
+ int save_erase, save_kill;
#endif
- /* get the current terminal attributes */
+ /* get the current terminal attributes */
#ifdef HAVE_TERMIOS_H
- tcgetattr(0, &tio);
+ tcgetattr(0, &tio);
#else
# ifdef HAVE_TERMIO_H
- ioctl(0, TCGETA, &tio);
+ ioctl(0, TCGETA, &tio);
# else
- ioctl (0, TIOCGETP, (char *) &tio);
- ioctl (0, TIOCGETC, (char *) &tc);
+ ioctl(0, TIOCGETP, (char *) &tio);
+ ioctl(0, TIOCGETC, (char *) &tc);
# endif
#endif
- /* save original kill, erase character for later */
- save_kill = KILL;
- save_erase = ERASE;
+ /* save original kill, erase character for later */
+ save_kill = KILL;
+ save_erase = ERASE;
- /* set new kill, erase character in terminal structure */
- KILL = killp ? chrcnv (killp) : save_kill;
- ERASE = erasep ? chrcnv (erasep) : save_erase;
+ /* set new kill, erase character in terminal structure */
+ KILL = killp ? chrcnv(killp) : save_kill;
+ ERASE = erasep ? chrcnv(erasep) : save_erase;
- /* set the new terminal attributes */
+ /* set the new terminal attributes */
#ifdef HAVE_TERMIOS_H
- tcsetattr(0, TCSADRAIN, &tio);
+ tcsetattr(0, TCSADRAIN, &tio);
#else
# ifdef HAVE_TERMIO_H
- ioctl(0, TCSETAW, &tio);
+ ioctl(0, TCSETAW, &tio);
# else
- ioctl (0, TIOCSETN, (char *) &tio);
+ ioctl(0, TIOCSETN, (char *) &tio);
# endif
#endif
- /* print out new kill erase characters */
- chrdsp ("erase", ERASE);
- chrdsp (", kill", KILL);
- chrdsp (", intr", INTR);
- putchar ('\n');
- fflush (stdout);
+ /* print out new kill erase characters */
+ chrdsp("erase", ERASE);
+ chrdsp(", kill", KILL);
+ chrdsp(", intr", INTR);
+ putchar('\n');
+ fflush(stdout);
- /*
- * We set the kill and erase character back to original
- * setup in terminal structure so we can easily
- * restore it upon exit.
- */
- KILL = save_kill;
- ERASE = save_erase;
- }
-
- sigint = 0;
- SIGNAL2 (SIGINT, intrser);
-
- /*
- * Loop through the lines of the draft skeleton.
- */
- for (state = FLD;;) {
- switch (state = m_getfld (state, name, field, sizeof(field), in)) {
- case FLD:
- case FLDEOF:
- case FLDPLUS:
/*
- * Check if the value of field contains anything
- * other than space or tab.
- */
- for (cp = field; *cp; cp++)
- if (*cp != ' ' && *cp != '\t')
- break;
+ ** We set the kill and erase character back to original
+ ** setup in terminal structure so we can easily
+ ** restore it upon exit.
+ */
+ KILL = save_kill;
+ ERASE = save_erase;
+ }
+
+ sigint = 0;
+ SIGNAL2(SIGINT, intrser);
- /* If so, just add header line to draft */
- if (*cp++ != '\n' || *cp != 0) {
- printf ("%s:%s", name, field);
- fprintf (out, "%s:%s", name, field);
- while (state == FLDPLUS) {
- state =
- m_getfld (state, name, field, sizeof(field), in);
- printf ("%s", field);
- fprintf (out, "%s", field);
- }
- } else {
- /* Else, get value of header field */
- printf ("%s: ", name);
- fflush (stdout);
- i = getln (field, sizeof(field));
- if (i == -1) {
+ /*
+ ** Loop through the lines of the draft skeleton.
+ */
+ for (state = FLD;;) {
+ switch (state = m_getfld(state, name, field, sizeof(field),
+ in)) {
+ case FLD:
+ case FLDEOF:
+ case FLDPLUS:
+ /*
+ ** Check if the value of field contains
+ ** anything other than space or tab.
+ */
+ for (cp = field; *cp; cp++)
+ if (*cp != ' ' && *cp != '\t')
+ break;
+
+ /* If so, just add header line to draft */
+ if (*cp++ != '\n' || *cp != 0) {
+ printf("%s:%s", name, field);
+ fprintf(out, "%s:%s", name, field);
+ while (state == FLDPLUS) {
+ state = m_getfld(state, name, field,
+ sizeof(field), in);
+ printf("%s", field);
+ fprintf(out, "%s", field);
+ }
+ } else {
+ /* Else, get value of header field */
+ printf("%s: ", name);
+ fflush(stdout);
+ i = getln(field, sizeof(field));
+ if (i == -1) {
abort:
- if (killp || erasep) {
+ if (killp || erasep) {
#ifdef HAVE_TERMIOS_H
- tcsetattr(0, TCSADRAIN, &tio);
+ tcsetattr(0, TCSADRAIN, &tio);
#else
# ifdef HAVE_TERMIO
- ioctl (0, TCSETA, &tio);
+ ioctl(0, TCSETA, &tio);
# else
- ioctl (0, TIOCSETN, (char *) &tio);
+ ioctl(0, TIOCSETN, (char *) &tio);
# endif
#endif
+ }
+ unlink(tmpfil);
+ done(1);
+ }
+ if (i != 0 || (field[0] != '\n' && field[0] != 0)) {
+ fprintf(out, "%s:", name);
+ do {
+ if (field[0] != ' ' && field[0] != '\t')
+ putc(' ', out);
+ fprintf(out, "%s", field);
+ } while (i == 1 && (i = getln(field, sizeof(field))) >= 0);
+ if (i == -1)
+ goto abort;
+ }
}
- unlink (tmpfil);
- done (1);
- }
- if (i != 0 || (field[0] != '\n' && field[0] != 0)) {
- fprintf (out, "%s:", name);
- do {
- if (field[0] != ' ' && field[0] != '\t')
- putc (' ', out);
- fprintf (out, "%s", field);
- } while (i == 1
- && (i = getln (field, sizeof(field))) >= 0);
- if (i == -1)
- goto abort;
- }
- }
- if (state == FLDEOF) { /* moby hack */
- fprintf (out, "--------\n");
- printf ("--------\n");
- if (!body)
- break;
- goto no_body;
- }
- continue;
-
- case BODY:
- case BODYEOF:
- case FILEEOF:
- if (!body)
- break;
- fprintf (out, "--------\n");
- if (field[0] == 0 || !prepend)
- printf ("--------\n");
- if (field[0]) {
- if (prepend && body) {
- printf ("\n--------Enter initial text\n\n");
- fflush (stdout);
- for (;;) {
- getln (buffer, sizeof(buffer));
- if (doteof && buffer[0] == '.' && buffer[1] == '\n')
- break;
- if (buffer[0] == 0)
+ if (state == FLDEOF) { /* moby hack */
+ fprintf(out, "--------\n");
+ printf("--------\n");
+ if (!body)
+ break;
+ goto no_body;
+ }
+ continue;
+
+ case BODY:
+ case BODYEOF:
+ case FILEEOF:
+ if (!body)
break;
- fprintf (out, "%s", buffer);
+ fprintf(out, "--------\n");
+ if (field[0] == 0 || !prepend)
+ printf("--------\n");
+ if (field[0]) {
+ if (prepend && body) {
+ printf("\n--------Enter initial text\n\n");
+ fflush(stdout);
+ for (;;) {
+ getln(buffer, sizeof(buffer));
+ if (doteof && buffer[0] == '.' && buffer[1] == '\n')
+ break;
+ if (buffer[0] == 0)
+ break;
+ fprintf(out, "%s", buffer);
+ }
+ }
+
+ do {
+ fprintf(out, "%s", field);
+ if (!rapid && !sigint)
+ printf("%s", field);
+ } while (state == BODY && (state = m_getfld(state, name, field, sizeof(field), in)));
+ if (prepend || !body)
+ break;
+ else
+ printf ("\n--------Enter additional text\n\n");
}
- }
-
- do {
- fprintf (out, "%s", field);
- if (!rapid && !sigint)
- printf ("%s", field);
- } while (state == BODY &&
- (state = m_getfld (state, name, field, sizeof(field), in)));
- if (prepend || !body)
- break;
- else
- printf ("\n--------Enter additional text\n\n");
- }
no_body:
- fflush (stdout);
- for (;;) {
- getln (field, sizeof(field));
- if (doteof && field[0] == '.' && field[1] == '\n')
- break;
- if (field[0] == 0)
+ fflush(stdout);
+ for (;;) {
+ getln(field, sizeof(field));
+ if (doteof && field[0] == '.' && field[1] == '\n')
+ break;
+ if (field[0] == 0)
+ break;
+ fprintf(out, "%s", field);
+ }
break;
- fprintf (out, "%s", field);
+
+ default:
+ adios(NULL, "skeleton is poorly formatted");
}
break;
-
- default:
- adios (NULL, "skeleton is poorly formatted");
}
- break;
- }
- if (body)
- printf ("--------\n");
+ if (body)
+ printf("--------\n");
- fflush (stdout);
- fclose (in);
- fclose (out);
- SIGNAL (SIGINT, SIG_IGN);
+ fflush(stdout);
+ fclose(in);
+ fclose(out);
+ SIGNAL(SIGINT, SIG_IGN);
- if (killp || erasep) {
+ if (killp || erasep) {
#ifdef HAVE_TERMIOS_H
- tcsetattr(0, TCSADRAIN, &tio);
+ tcsetattr(0, TCSADRAIN, &tio);
#else
# ifdef HAVE_TERMIO_H
- ioctl (0, TCSETAW, &tio);
+ ioctl(0, TCSETAW, &tio);
# else
- ioctl (0, TIOCSETN, (char *) &tio);
+ ioctl(0, TIOCSETN, (char *) &tio);
# endif
#endif
- }
-
- if ((fdi = open (tmpfil, O_RDONLY)) == NOTOK)
- adios (tmpfil, "unable to re-open");
- if ((fdo = creat (drft, m_gmprot ())) == NOTOK)
- adios (drft, "unable to write");
- cpydata (fdi, fdo, tmpfil, drft);
- close (fdi);
- close (fdo);
- unlink (tmpfil);
-
- context_save (); /* save the context file */
- return done (0);
+ }
+
+ if ((fdi = open(tmpfil, O_RDONLY)) == NOTOK)
+ adios(tmpfil, "unable to re-open");
+ if ((fdo = creat(drft, m_gmprot())) == NOTOK)
+ adios(drft, "unable to write");
+ cpydata(fdi, fdo, tmpfil, drft);
+ close(fdi);
+ close(fdo);
+ unlink(tmpfil);
+
+ context_save(); /* save the context file */
+ done(0);
+ return 1;
}
int
-getln (char *buffer, int n)
+getln(char *buffer, int n)
{
- int c;
- char *cp;
-
- cp = buffer;
- *cp = 0;
-
- switch (setjmp (sigenv)) {
- case OK:
- wtuser = 1;
- break;
-
- case DONE:
- wtuser = 0;
- return 0;
-
- default:
- wtuser = 0;
- return NOTOK;
- }
-
- for (;;) {
- switch (c = getchar ()) {
- case EOF:
- clearerr (stdin);
- longjmp (sigenv, DONE);
-
- case '\n':
- if (cp[-1] == QUOTE) {
- cp[-1] = c;
- wtuser = 0;
- return 1;
- }
- *cp++ = c;
- *cp = 0;
+ int c;
+ char *cp;
+
+ cp = buffer;
+ *cp = 0;
+
+ switch (setjmp(sigenv)) {
+ case OK:
+ wtuser = 1;
+ break;
+
+ case DONE:
wtuser = 0;
return 0;
- default:
- if (cp < buffer + n)
- *cp++ = c;
- *cp = 0;
+ default:
+ wtuser = 0;
+ return NOTOK;
+ }
+
+ for (;;) {
+ switch (c = getchar()) {
+ case EOF:
+ clearerr(stdin);
+ longjmp(sigenv, DONE);
+
+ case '\n':
+ if (cp[-1] == QUOTE) {
+ cp[-1] = c;
+ wtuser = 0;
+ return 1;
+ }
+ *cp++ = c;
+ *cp = 0;
+ wtuser = 0;
+ return 0;
+
+ default:
+ if (cp < buffer + n)
+ *cp++ = c;
+ *cp = 0;
+ }
}
- }
}
static RETSIGTYPE
-intrser (int i)
+intrser(int i)
{
-#ifndef RELIABLE_SIGNALS
- SIGNAL (SIGINT, intrser);
+#ifndef RELIABLE_SIGNALS
+ SIGNAL(SIGINT, intrser);
#endif
- if (wtuser)
- longjmp (sigenv, NOTOK);
- sigint++;
+ if (wtuser)
+ longjmp(sigenv, NOTOK);
+ sigint++;
}
static int
-chrcnv (char *cp)
+chrcnv(char *cp)
{
- return (*cp != QUOTE ? *cp : m_atoi (++cp));
+ return (*cp != QUOTE ? *cp : m_atoi(++cp));
}
static void
-chrdsp (char *s, char c)
+chrdsp(char *s, char c)
{
- printf ("%s ", s);
- if (c < ' ' || c == 0177)
- printf ("^%c", c ^ 0100);
- else
- printf ("%c", c);
+ printf("%s ", s);
+ if (c < ' ' || c == 0177)
+ printf("^%c", c ^ 0100);
+ else
+ printf("%c", c);
}