#include <errno.h>
#include <signal.h>
#include <setjmp.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <locale.h>
+#include <sysexits.h>
static struct swit switches[] = {
#define PREPSW 0
{ NULL, 0 }
};
+char *version=VERSION;
-static int wtuser = 0;
-static int sigint = 0;
+volatile sig_atomic_t wtuser = 0;
+volatile sig_atomic_t sigint = 0;
static jmp_buf sigenv;
/*
main(int argc, char **argv)
{
int qbody = 1, prepend = 1, rapid = 0;
- int fdi, fdo, i, state;
+ int fdi, fdo, i;
char *cp, *drft = NULL;
- char name[NAMESZ], field[BUFSIZ];
+ enum state state;
+ struct field f = {{0}};
char buffer[BUFSIZ], tmpfil[BUFSIZ];
char **arguments, **argp;
FILE *in, *out;
switch (smatch(++cp, switches)) {
case AMBIGSW:
ambigsw(cp, switches);
- exit(1);
+ exit(EX_USAGE);
case UNKWNSW:
- adios(NULL, "-%s unknown", cp);
+ adios(EX_USAGE, NULL, "-%s unknown", cp);
case HELPSW:
snprintf(buffer, sizeof(buffer),
"%s [switches] file",
invo_name);
print_help(buffer, switches, 1);
- exit(0);
+ exit(argc == 2 ? EX_OK : EX_USAGE);
+
case VERSIONSW:
print_version(invo_name);
- exit(0);
+ exit(argc == 2 ? EX_OK : EX_USAGE);
case PREPSW:
prepend++;
}
}
- if (!drft)
- adios(NULL, "usage: %s [switches] file", invo_name);
- if ((in = fopen(drft, "r")) == NULL)
- adios(drft, "unable to open");
+ if (!drft) {
+ adios(EX_USAGE, NULL, "usage: %s [switches] file", invo_name);
+ }
+ if ((in = fopen(drft, "r")) == NULL) {
+ adios(EX_IOERR, drft, "unable to open");
+ }
tfile = m_mktemp2(NULL, invo_name, NULL, &out);
- if (tfile == NULL)
- adios("prompter", "unable to create temporary file");
+ if (tfile == NULL) {
+ adios(EX_CANTCREAT, "prompter", "unable to create temporary file");
+ }
chmod(tmpfil, 0600);
strncpy(tmpfil, tfile, sizeof(tmpfil));
/*
** 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:
+ for (state = FLD2;;) {
+ switch (state = m_getfld2(state, &f, in)) {
+ case LENERR2:
+ state = FLD2;
+ /* FALL */
+
+ case FLD2:
/*
** Check if the value of field contains
** anything other than space or tab.
*/
- for (cp = field; *cp; cp++)
- if (*cp != ' ' && *cp != '\t')
+ for (cp = f.value; *cp; cp++) {
+ if (*cp != ' ' && *cp != '\t') {
break;
+ }
+ }
/* If so, just add header line to draft */
if (*cp++ != '\n' || *cp) {
- 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);
- }
+ printf("%s:%s", f.name, f.value);
+ fprintf(out, "%s:%s", f.name, f.value);
} else {
/* Else, get value of header field */
- printf("%s: ", name);
+ printf("%s: ", f.name);
fflush(stdout);
- i = getln(field, sizeof(field));
+ i = getln(buffer, sizeof(buffer));
if (i == -1) {
abort:
unlink(tmpfil);
- /* sysexits.h EX_DATAERR */
- exit(1);
+ exit(EX_DATAERR);
}
- if (i || (field[0]!='\n' && field[0]!='\0')) {
- fprintf(out, "%s:", name);
+ if (i || (buffer[0]!='\n' && buffer[0]!='\0')) {
+ fprintf(out, "%s:", f.name);
do {
- if (field[0] != ' ' && field[0] != '\t')
+ if (buffer[0] != ' ' && buffer[0] != '\t') {
putc(' ', out);
- fprintf(out, "%s", field);
- } while (i == 1 && (i = getln(field, sizeof(field))) >= 0);
- if (i == -1)
+ }
+ fprintf(out, "%s", buffer);
+ } while (i == 1 && (i = getln(buffer, sizeof(buffer))) >= 0);
+ if (i == -1) {
goto abort;
+ }
}
}
-
- if (state == FLDEOF) { /* moby hack */
- /* draft has no body separator; only headers */
- fprintf(out, "--------\n");
- if (!qbody)
- break;
- printf("--------\n");
- goto has_no_body;
- }
continue;
- case BODY:
- case BODYEOF:
- case FILEEOF:
+ case BODY2:
+ case FILEEOF2:
fprintf(out, "--------\n");
if (qbody) {
- if (!*field) {
+ if (f.value == NULL) {
printf("--------\n");
goto has_no_body;
}
fflush(stdout);
for (;;) {
getln(buffer, sizeof(buffer));
- if (!*buffer)
+ if (!*buffer) {
break;
+ }
fprintf(out, "%s", buffer);
}
} else {
}
}
- do {
- fprintf(out, "%s", field);
- if (!rapid && !sigint)
- printf("%s", field);
- } while (state == BODY &&
- (state = m_getfld(state, name,
- field, sizeof(field), in)));
+ if (state == BODY2) {
+ do {
+ fprintf(out, "%s", f.value);
+ if (!rapid && !sigint) {
+ printf("%s", f.value);
+ }
+ } while ((state = m_getfld2(state, &f, in))
+ ==BODY2);
+ if (state != FILEEOF2) {
+ adios(EX_IOERR, "m_getfld2", "io error");
+ }
+ }
- if (prepend || !qbody)
+ if (prepend || !qbody) {
break;
+ }
printf("--------Enter additional text\n");
has_no_body:
fflush(stdout);
for (;;) {
- getln(field, sizeof(field));
- if (!*field)
+ getln(buffer, sizeof(buffer));
+ if (!*buffer) {
break;
- fprintf(out, "%s", field);
+ }
+ fprintf(out, "%s", buffer);
}
break;
+ case FMTERR2:
+ advise(NULL, "skeleton is poorly formatted");
+ continue;
default:
- adios(NULL, "skeleton is poorly formatted");
+ adios(EX_IOERR, "m_getfld2", "io error");
}
break;
}
- if (qbody)
+ if (qbody) {
printf("--------\n");
+ }
fflush(stdout);
fclose(in);
fclose(out);
SIGNAL(SIGINT, SIG_IGN);
- 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");
+ if ((fdi = open(tmpfil, O_RDONLY)) == NOTOK) {
+ adios(EX_IOERR, tmpfil, "unable to re-open");
+ }
+ if ((fdo = creat(drft, m_gmprot())) == NOTOK) {
+ adios(EX_IOERR, drft, "unable to write");
+ }
cpydata(fdi, fdo, tmpfil, drft);
close(fdi);
close(fdo);
unlink(tmpfil);
- context_save(); /* save the context file */
- return 0;
+ context_save();
+ return EX_OK;
}
getln(char *buffer, int n)
{
int c;
+ sig_atomic_t psigint = sigint;
char *cp;
cp = buffer;
wtuser = 1;
break;
- case DONE:
- wtuser = 0;
- return 0;
-
default:
wtuser = 0;
- return NOTOK;
+ if (sigint == psigint) {
+ return 0;
+ } else {
+ sigint = psigint;
+ return NOTOK;
+ }
}
for (;;) {
static void
intrser(int i)
{
- if (wtuser)
- longjmp(sigenv, NOTOK);
+ if (wtuser) {
+ close(STDIN_FILENO);
+ }
sigint++;
}