3 * prompter.c -- simple prompting editor front-end
10 #include <h/signals.h>
35 static struct swit switches[] = {
66 static struct termios tio;
67 # define ERASE tio.c_cc[VERASE]
68 # define KILL tio.c_cc[VKILL]
69 # define INTR tio.c_cc[VINTR]
72 static struct termio tio;
73 # define ERASE tio.c_cc[VERASE]
74 # define KILL tio.c_cc[VKILL]
75 # define INTR tio.c_cc[VINTR]
77 static struct sgttyb tio;
78 static struct tchars tc;
79 # define ERASE tio.sg_erase
80 # define KILL tio.sg_kill
81 # define INTR tc.t_intrc
85 static int wtuser = 0;
86 static int sigint = 0;
87 static jmp_buf sigenv;
92 int getln (char *, int);
93 static int chrcnv (char *);
94 static void chrdsp (char *, char);
95 static RETSIGTYPE intrser (int);
99 main (int argc, char **argv)
101 int body = 1, prepend = 1, rapid = 0;
102 int doteof = 0, fdi, fdo, i, state;
103 char *cp, *drft = NULL, *erasep = NULL;
104 char *killp = NULL, name[NAMESZ], field[BUFSIZ];
105 char buffer[BUFSIZ], tmpfil[BUFSIZ];
106 char **arguments, **argp;
110 setlocale(LC_ALL, "");
112 invo_name = r1bindex (argv[0], '/');
114 /* read user profile/context */
117 arguments = getarguments (invo_name, argc, argv, 1);
120 while ((cp = *argp++))
122 switch (smatch (++cp, switches)) {
124 ambigsw (cp, switches);
127 adios (NULL, "-%s unknown", cp);
130 snprintf (buffer, sizeof(buffer), "%s [switches] file",
132 print_help (buffer, switches, 1);
135 print_version(invo_name);
139 if (!(erasep = *argp++) || *erasep == '-')
140 adios (NULL, "missing argument to %s", argp[-2]);
143 if (!(killp = *argp++) || *killp == '-')
144 adios (NULL, "missing argument to %s", argp[-2]);
181 adios (NULL, "usage: %s [switches] file", invo_name);
182 if ((in = fopen (drft, "r")) == NULL)
183 adios (drft, "unable to open");
185 strncpy (tmpfil, m_tmpfil (invo_name), sizeof(tmpfil));
186 if ((out = fopen (tmpfil, "w")) == NULL)
187 adios (tmpfil, "unable to create");
188 chmod (tmpfil, 0600);
191 * Are we changing the kill or erase character?
193 if (killp || erasep) {
194 #ifdef HAVE_TERMIOS_H
195 cc_t save_erase, save_kill;
197 int save_erase, save_kill;
200 /* get the current terminal attributes */
201 #ifdef HAVE_TERMIOS_H
204 # ifdef HAVE_TERMIO_H
205 ioctl(0, TCGETA, &tio);
207 ioctl (0, TIOCGETP, (char *) &tio);
208 ioctl (0, TIOCGETC, (char *) &tc);
212 /* save original kill, erase character for later */
216 /* set new kill, erase character in terminal structure */
217 KILL = killp ? chrcnv (killp) : save_kill;
218 ERASE = erasep ? chrcnv (erasep) : save_erase;
220 /* set the new terminal attributes */
221 #ifdef HAVE_TERMIOS_H
222 tcsetattr(0, TCSADRAIN, &tio);
224 # ifdef HAVE_TERMIO_H
225 ioctl(0, TCSETAW, &tio);
227 ioctl (0, TIOCSETN, (char *) &tio);
231 /* print out new kill erase characters */
232 chrdsp ("erase", ERASE);
233 chrdsp (", kill", KILL);
234 chrdsp (", intr", INTR);
239 * We set the kill and erase character back to original
240 * setup in terminal structure so we can easily
241 * restore it upon exit.
248 SIGNAL2 (SIGINT, intrser);
251 * Loop through the lines of the draft skeleton.
253 for (state = FLD;;) {
254 switch (state = m_getfld (state, name, field, sizeof(field), in)) {
259 * Check if the value of field contains anything
260 * other than space or tab.
262 for (cp = field; *cp; cp++)
263 if (*cp != ' ' && *cp != '\t')
266 /* If so, just add header line to draft */
267 if (*cp++ != '\n' || *cp != 0) {
268 printf ("%s:%s", name, field);
269 fprintf (out, "%s:%s", name, field);
270 while (state == FLDPLUS) {
272 m_getfld (state, name, field, sizeof(field), in);
273 printf ("%s", field);
274 fprintf (out, "%s", field);
277 /* Else, get value of header field */
278 printf ("%s: ", name);
280 i = getln (field, sizeof(field));
283 if (killp || erasep) {
284 #ifdef HAVE_TERMIOS_H
285 tcsetattr(0, TCSADRAIN, &tio);
288 ioctl (0, TCSETA, &tio);
290 ioctl (0, TIOCSETN, (char *) &tio);
297 if (i != 0 || (field[0] != '\n' && field[0] != 0)) {
298 fprintf (out, "%s:", name);
300 if (field[0] != ' ' && field[0] != '\t')
302 fprintf (out, "%s", field);
304 && (i = getln (field, sizeof(field))) >= 0);
310 if (state == FLDEOF) { /* moby hack */
311 fprintf (out, "--------\n");
312 printf ("--------\n");
324 fprintf (out, "--------\n");
325 if (field[0] == 0 || !prepend)
326 printf ("--------\n");
328 if (prepend && body) {
329 printf ("\n--------Enter initial text\n\n");
332 getln (buffer, sizeof(buffer));
333 if (doteof && buffer[0] == '.' && buffer[1] == '\n')
337 fprintf (out, "%s", buffer);
342 fprintf (out, "%s", field);
343 if (!rapid && !sigint)
344 printf ("%s", field);
345 } while (state == BODY &&
346 (state = m_getfld (state, name, field, sizeof(field), in)));
347 if (prepend || !body)
350 printf ("\n--------Enter additional text\n\n");
355 getln (field, sizeof(field));
356 if (doteof && field[0] == '.' && field[1] == '\n')
360 fprintf (out, "%s", field);
365 adios (NULL, "skeleton is poorly formatted");
371 printf ("--------\n");
376 SIGNAL (SIGINT, SIG_IGN);
378 if (killp || erasep) {
379 #ifdef HAVE_TERMIOS_H
380 tcsetattr(0, TCSADRAIN, &tio);
382 # ifdef HAVE_TERMIO_H
383 ioctl (0, TCSETAW, &tio);
385 ioctl (0, TIOCSETN, (char *) &tio);
390 if ((fdi = open (tmpfil, O_RDONLY)) == NOTOK)
391 adios (tmpfil, "unable to re-open");
392 if ((fdo = creat (drft, m_gmprot ())) == NOTOK)
393 adios (drft, "unable to write");
394 cpydata (fdi, fdo, tmpfil, drft);
399 context_save (); /* save the context file */
405 getln (char *buffer, int n)
413 switch (setjmp (sigenv)) {
428 switch (c = getchar ()) {
431 longjmp (sigenv, DONE);
434 if (cp[-1] == QUOTE) {
456 #ifndef RELIABLE_SIGNALS
457 SIGNAL (SIGINT, intrser);
461 longjmp (sigenv, NOTOK);
469 return (*cp != QUOTE ? *cp : m_atoi (++cp));
474 chrdsp (char *s, char c)
477 if (c < ' ' || c == 0177)
478 printf ("^%c", c ^ 0100);