]> diplodocus.org Git - nmh/blob - docs/historical/SRI-NOSC/prompter.c
Added start_test/finish_test to a bunch of tests.
[nmh] / docs / historical / SRI-NOSC / prompter.c
1 #include "mh.h"
2 #include "iobuf.h"
3 #include "errors.h"
4 #include "sgtty.h"
5 #include "signals.h"
6
7 /*#define CEDIT 01 */ /* use following editing chars */
8 #define CKILL 006 /* @ => <CLOSE> */
9 #define CERASE 001 /* # => <CTRL A> */
10
11 /*define EDIT 001*/ /* edit after filling in fields */
12 char sysed[];
13
14 int fout;
15 struct iobuf in, out;
16 struct sgtty sg;
17 struct swit switches[] {
18 "editor editor", 0, /* 0 */
19 "erase chr", 2, /* 1 */
20 "kill chr", 0, /* 2 */
21 "help", 4, /* 3 */
22 0, 0
23 };
24
25
26 main(argc, argv)
27 char *argv[];
28 {
29 char tmpfil[32], *drft, name[NAMESZ], field[512], *ed;
30 int exitstat;
31 char skill, serase;
32 char *killp, *erasep;
33 register int i, state;
34 register char *cp;
35 char *ap;
36 char *arguments[50], **argp;
37 int sig();
38 int status, pid, wpid, intr;
39
40 fout = dup(1);
41 skill = exitstat = 0;
42 ap = cp = argv[0];
43 while(*cp)
44 if(*cp++ == '/')
45 ap = cp;
46 if((cp = m_find(ap)) != -1) {
47 ap = brkstring(cp = getcpy(cp), " ", '\n');
48 ap = copyip(ap, arguments);
49 } else
50 ap = arguments;
51 copyip(argv+1, ap);
52 argp = arguments;
53 while(cp = *argp++)
54 if(*cp == '-')
55 switch(smatch(++cp, switches)) {
56 case -2:ambigsw(cp, switches); /* ambiguous */
57 goto badleave;
58 /* unknown */
59 case -1:printf("prompter: -%s unknown\n", cp);
60 goto badleave;
61 case 0: if(!(ed = *argp++)) { /* -editor */
62 missing: printf("prompter: Missing argument for %s switch\n", argp[-2]);
63 goto badleave;
64 }
65 continue;
66 case 1: if(!(erasep = *argp++)) /* -erase */
67 goto missing;
68 continue;
69 case 2: if(!(killp= *argp++)) /* -kill */
70 goto missing;
71 continue;
72 case 3: help("prompter [file] [switches]",
73 switches);
74 goto badleave;
75 }
76 else
77 drft = cp;
78 if(!drft) {
79 printf("prompter: missing skeleton\n");
80 goto badleave;
81 }
82 if(fopen(drft, &in) == -1) {
83 printf("Can't open %s\n", drft);
84 goto badleave;
85 }
86 copy(makename("prmt", ".tmp"), copy("/tmp/", tmpfil));
87 if(fcreat(tmpfil, &out) == -1) {
88 printf("Can't create %s\n", tmpfil);
89 goto badleave;
90 }
91 chmod(tmpfil, 0700);
92 signal(SIGINT, &sig);
93 gtty(0, &sg);
94 skill = sg.sg_kill;
95 serase = sg.sg_erase;
96 #ifdef CEDIT
97 sg.sg_kill = killp ? chrcnv(killp) : CKILL;
98 sg.sg_erase = erasep ? chrcnv(erasep) : CERASE;
99 #else
100 sg.sg_kill = killp ? chrcnv(killp) : skill;
101 sg.sg_erase = erasep ? chrcnv(erasep) : serase;
102 #endif
103 stty(0, &sg);
104 if ( skill != sg.sg_kill || serase != sg.sg_erase ) {
105 printf("Erase Char="); chrdisp(sg.sg_erase);
106 printf("; Kill Line="); chrdisp(sg.sg_kill);
107 printf(".\n"); flush();
108 }
109
110 state = FLD;
111 for(;;) switch(state = m_getfld(state,name,field,sizeof field,&in)) {
112
113 case FLD:
114 case FLDEOF:
115 case FLDPLUS:
116 if(field[0] != '\n' || field[1] != 0) {
117 printf("%s:%s", name, field);
118 puts(name, &out);
119 putc(':', &out);
120 puts(field, &out);
121 while(state == FLDPLUS) {
122 state=m_getfld(state,name,field,sizeof field,&in);
123 printf("%s", field);
124 puts(field, &out);
125 }
126 } else {
127 printf("%s: ", name);
128 flush();
129 i = getln(&field);
130 if(i == -1)
131 goto badleave;
132 if(i == 0 && (field[0] == '\n' || !field[0]))
133 continue;
134 puts(name, &out); putc(':', &out);
135 do {
136 if(field[0] != ' ' && field[0] != '\t')
137 putc(' ', &out);
138 puts(field, &out);
139 } while(i == 1 && (i = getln(&field)) >= 0);
140 if(i == -1)
141 goto badleave;
142 }
143 field[0] = 0;
144 if(state == FLDEOF)
145 goto body;
146 continue;
147
148 case BODY:
149 case BODYEOF:
150 case FILEEOF:
151 body: puts("--------\n", &out);
152 printf("--------\n");
153 if(field[0]) {
154 do {
155 puts(field, &out);
156 /*printf("%s", field);*/
157 } while(state == BODY &&
158 (state=m_getfld(state,name,field,sizeof field,&in)));
159 }
160 flush();
161 for(;;) {
162 i = getln(&field);
163 if (i == -1) goto badleave; /**/
164 if(field[0] == 0)
165 break;
166 puts(field, &out);
167 }
168 goto done;
169
170 default:
171 printf("Bad format file!\n");
172 goto badleave;
173 }
174
175
176 done:
177 printf("--------\n"); flush();
178 fflush(&out);
179 close(out.b_fildes);
180 fopen(tmpfil, &out);
181 close(in.b_fildes);
182 fcreat(drft, &in); /* Truncate prior to copy back */
183 do
184 if((i = read(out.b_fildes, field, sizeof field)) > 0)
185 write(in.b_fildes, field, i);
186 while(i == sizeof field);
187 close(in.b_fildes);
188 close(out.b_fildes);
189 unlink(tmpfil);
190 again:
191 if(skill) {
192 sg.sg_kill = skill;
193 sg.sg_erase = serase;
194 stty(0, &sg);
195 skill = 0;
196 }
197
198 #ifdef EDIT
199 printf("Edit? ");
200 flush();
201 getln(&field);
202 if(field[0] == 0)
203 goto badleave;
204 field[length(field) - 1] = 0; /* zap <lf> */
205 if(field[0] == 0) {
206 printf("Options are:\n no\n yes\n show\n <any editor>\n");
207 goto again;
208 }
209 if(ssequal(field, "no"))
210 goto leave;
211 if(ssequal(field, "show")) {
212 if(showfile(drft))
213 goto badleave;
214 goto again;
215 }
216 if(ssequal(field, "yes")) {
217 if(!ed &&
218 ((ed = m_find("editor")) == -1 || equal(invo_name(), ed)))
219 ed = sysed;
220 } else
221 ed = field;
222 intr = signal(SIGINT, 1);
223 if((pid = fork()) == 0) {
224 /* m_update(); */
225 flush();
226 execlsrh(ed, drft, 0);
227 exit(-1); /* can't exec editor */
228 } else if(pid == -1) {
229 printf("prompter: no forks!\n");
230 goto leave;
231 } else
232 while((wpid = waita(&status)) != -1 && wpid != pid) ;
233 if((status & 0177400) == 0177400) goto again; /* -1 */
234 signal(SIGINT, intr);
235 #endif
236 goto leave;
237
238 badleave:
239 exitstat = 1;
240 leave:
241 m_update();
242 flush();
243 if(skill) {
244 sg.sg_kill = skill;
245 sg.sg_erase = serase;
246 stty(0, &sg);
247 }
248 exit(exitstat);
249 }
250
251
252
253
254 getln(buf)
255 char *buf;
256 {
257 register char *cp;
258 register int c;
259
260 cp = buf;
261 *cp = 0;
262 for(;;) {
263 c = getchar();
264 if(c == 0)
265 if(errno == EINTR)
266 return(-1);
267 else
268 return(0);
269 if(c == '\n') {
270 if ( cp != buf ) /* if not first char in line */
271 if(cp[-1] == '\\') {
272 cp[-1] = c;
273 return(1);
274 }
275 if((buf==&(cp[-1]))&&(cp[-1] == '.')) {
276 buf[0] = 0;
277 return(0);
278 }
279 *cp++ = c;
280 *cp = 0;
281 return(0);
282 }
283 if(cp < buf + 500)
284 *cp++ = c;
285 *cp = 0;
286 }
287 }
288
289
290 sig()
291 {
292 signal(SIGINT, &sig);
293 return;
294 }
295
296
297 chrcnv(str)
298 {
299 register char *cp;
300 register int c;
301
302 cp = str;
303 if((c = *cp++) != '\\')
304 return(c);
305 c = 0;
306 while(*cp && *cp != '\n') {
307 c =* 8;
308 c =+ *cp++ - '0';
309 }
310 return c;
311 }
312
313
314 chrdisp(chr)
315 {
316 register int c;
317
318 c = chr;
319 if(c < ' ')
320 printf("<CTRL-%c>", c + '@');
321 else
322 printf("%c", c);
323 }