]> diplodocus.org Git - nmh/blob - docs/historical/mh-jun-1982/progs/prompter.c
Replaced use of snprintf() with memcpy()/memmove().
[nmh] / docs / historical / mh-jun-1982 / progs / prompter.c
1 #ifdef COMMENT
2 Proprietary Rand Corporation, 1981.
3 Further distribution of this software
4 subject to the terms of the Rand
5 license agreement.
6 #endif
7
8 #include "../mh.h"
9 #include <stdio.h>
10 #include <errno.h>
11 #include <sgtty.h>
12 #include <signal.h>
13 #include <strings.h>
14
15 #define CKILL 006 /* @ => <CLOSE> */
16 #define CERASE 001 /* # => <CTRL A> */
17
18 int wtuser; /* waiting for user input */
19 int sigint; /* sensed an interrupt */
20 FILE *in, *out;
21 struct sgttyb sg;
22 struct swit switches[] = {
23 "erase chr", 2, /* 0 */ /* "2" can become "0",since no ed */
24 "kill chr", 0, /* 1 */
25 "help", 4, /* 2 */
26 0, 0
27 };
28
29 extern int errno; /* MLW 4bsd does not have errno defined in errno.h */
30 extern char _sobuf[]; /* MLW standard out buffer */
31
32 /*ARGSUSED*/
33 main(argc, argv)
34 char *argv[];
35 {
36 char tmpfil[32], *drft, name[NAMESZ], field[BUFSIZ];
37 int exitstat;
38 char skill, serase;
39 char *killp, *erasep;
40 register int i, state;
41 register char *cp;
42 char **ap;
43 char *arguments[50], **argp;
44 int sig();
45
46 invo_name = argv[0];
47 setbuf(stdout, _sobuf);
48 tmpfil[0] = 0;
49 skill = 0; exitstat = 0;
50 cp = r1bindex(argv[0], '/');
51 if((cp = m_find(cp)) != NULL) {
52 ap = brkstring(cp = getcpy(cp), " ", "\n");
53 ap = copyip(ap, arguments);
54 } else
55 ap = arguments;
56 VOID copyip(argv+1, ap);
57 argp = arguments;
58 drft = NULLCP;
59 while(cp = *argp++)
60 if(*cp == '-')
61 switch(smatch(++cp, switches)) {
62 case -2:ambigsw(cp, switches); /* ambiguous */
63 goto badleave;
64 /* unknown */
65 case -1:fprintf(stderr, "prompter: -%s unknown\n", cp);
66 goto badleave;
67 case 0: if(!(erasep = *argp++)) { /* -erase */
68 missing: fprintf(stderr, "prompter: Missing argument for %s switch\n", argp[-2]);
69 goto badleave;
70 }
71 continue;
72 case 1: if(!(killp= *argp++)) /* -kill */
73 goto missing;
74 continue;
75 /* -help */
76 case 2: help("prompter [switches]",
77 switches);
78 goto badleave;
79 }
80 else if (!drft)
81 drft = cp;
82 if(!drft) {
83 fprintf(stderr, "prompter: missing skeleton\n");
84 goto badleave;
85 }
86 if((in = fopen(drft, "r")) == NULL) {
87 fprintf(stderr, "Can't open %s\n", drft);
88 goto badleave;
89 }
90 VOID copy(makename("prmt", ".tmp"), copy("/tmp/", tmpfil));
91 if((out = fopen(tmpfil, "w")) == NULL) {
92 fprintf(stderr, "Can't create %s\n", tmpfil);
93 goto badleave;
94 }
95 VOID chmod(tmpfil, 0700);
96 VOID signal(SIGINT, sig);
97 VOID gtty(0, &sg);
98 skill = sg.sg_kill;
99 serase = sg.sg_erase;
100 sg.sg_kill = killp ? chrcnv(killp) : skill;
101 sg.sg_erase = erasep ? chrcnv(erasep) : serase;
102 /*** stty(0, &sg); ***/
103 ioctl(0, TIOCSETN, &sg);
104 if(killp || erasep) {
105 printf("Erase Char="); chrdisp(sg.sg_erase);
106 printf("; Kill Line="); chrdisp(sg.sg_kill);
107 printf(".\n"); VOID fflush(stdout);
108 }
109 state = FLD;
110 for(;;) switch(state = m_getfld(state,name,field,sizeof field,in)) {
111
112 case FLD:
113 case FLDEOF:
114 case FLDPLUS:
115 if(field[0] != '\n' || field[1] != 0) {
116 printf("%s:%s", name, field);
117 fprintf(out, "%s:%s", name, field);
118 while(state == FLDPLUS) {
119 state=m_getfld(state,name,field,sizeof field,in);
120 printf("%s", field);
121 fprintf(out, "%s", field);
122 }
123 } else {
124 printf("%s: ", name);
125 VOID fflush(stdout);
126 i = getln(field);
127 if(i == -1)
128 goto badleave;
129 if(i == 0 && (field[0] == '\n' || !field[0]))
130 continue;
131 fprintf(out, "%s:", name);
132 do {
133 if(field[0] != ' ' && field[0] != '\t')
134 putc(' ', out);
135 fputs(field, out);
136 } while(i == 1 && (i = getln(field)) >= 0);
137 if(i == -1)
138 goto badleave;
139 }
140 field[0] = 0;
141 if(state == FLDEOF)
142 goto body;
143 continue;
144
145 case BODY:
146 case BODYEOF:
147 case FILEEOF:
148 body: fputs("--------\n", out);
149 printf("--------\n");
150 if(field[0]) {
151 do {
152 fputs(field, out);
153 if(!sigint)
154 printf("%s", field);
155 } while(state == BODY &&
156 (state=m_getfld(state,name,field,sizeof field,in)));
157 printf("\n--------Enter additional text\n\n");
158 }
159 VOID fflush(stdout);
160 for(;;) {
161 VOID getln(field);
162 if(field[0] == 0)
163 break;
164 fputs(field, out);
165 }
166 goto finish;
167
168 default:
169 fprintf(stderr, "Bad format file!\n");
170 goto badleave;
171 }
172
173
174 finish:
175 printf("--------\n"); VOID fflush(stdout);
176 VOID fclose(out);
177 out = fopen(tmpfil, "r");
178 VOID fclose(in);
179 in = fopen(drft, "w"); /* Truncate prior to copy back */
180 do
181 if((i = read(fileno(out), field, sizeof field)) > 0)
182 if(write(fileno(in), field, i) != i) {
183 fprintf(stderr, "Write error to ");
184 perror(drft);
185 done(1);
186 }
187 while(i == sizeof field);
188 goto leave;
189
190 badleave:
191 exitstat = 1;
192
193 leave:
194 if(in)
195 VOID fclose(in);
196 if(out)
197 VOID fclose(out);
198 if(tmpfil[0])
199 VOID unlink(tmpfil);
200 m_update();
201 if(killp || erasep) {
202 sg.sg_kill = skill;
203 sg.sg_erase = serase;
204 /*** stty(0, &sg); ***/
205 ioctl(0, TIOCSETN, &sg);
206 }
207 done(exitstat);
208 }
209
210
211 getln(buf)
212 char *buf;
213 {
214 register char *cp;
215 register int c;
216 int stat;
217
218 cp = buf;
219 *cp = 0;
220 wtuser = 1;
221 for(;;) {
222 c = getchar();
223 /*** fprintf(stderr,"getchar()=\\%o,errno=%d,EINTR=%d\n",c,errno,EINTR);/***/
224 if(c == EOF)
225 if(errno == EINTR) {
226 stat = -1;
227 goto leave;
228 } else {
229 stat = 0;
230 goto leave;
231 }
232 if(c == '\n') {
233 if(cp[-1] == '\\') {
234 cp[-1] = c;
235 stat = 1;
236 goto leave;
237 }
238 *cp++ = c;
239 *cp = 0;
240 stat = 0;
241 goto leave;
242 }
243 if(cp < buf + 500)
244 *cp++ = c;
245 *cp = 0;
246 }
247 leave: wtuser = 0;
248 return(stat);
249 }
250
251
252 sig()
253 {
254 VOID signal(SIGINT, sig);
255 if(!wtuser)
256 sigint = 1;
257 return;
258 }
259
260
261 chrcnv(str)
262 char *str;
263 {
264 register char *cp;
265 register int c;
266
267 cp = str;
268 if((c = *cp++) != '\\')
269 return(c);
270 c = 0;
271 while(*cp && *cp != '\n') {
272 c *= 8;
273 c += *cp++ - '0';
274 }
275 return c;
276 }
277
278
279 chrdisp(chr)
280 {
281 register int c;
282
283 c = chr;
284 if(c < ' ')
285 printf("<CTRL-%c>", c + '@');
286 else
287 printf("%c"