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