1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /* Copyright (c) 1988 AT&T */
22 /* All Rights Reserved */
23 /*
24 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27 /*
28 * Copyright 2006-2020 J. Schilling
29 *
30 * @(#)dohist.c 1.12 20/09/06 J. Schilling
31 */
32 #if defined(sun)
33 #pragma ident "@(#)dohist.c 1.12 20/09/06 J. Schilling"
34 #endif
35 /*
36 * @(#)dohist.c 1.7 06/12/12
37 */
38
39 #if defined(sun)
40 #pragma ident "@(#)dohist.c"
41 #pragma ident "@(#)sccs:lib/comobj/dohist.c"
42 #endif
43 # include <defines.h>
44 # define VMS_VFORK_OK
45 # include <schily/vfork.h>
46 # include <schily/wait.h>
47 # include <schily/fcntl.h>
48 # include <had.h>
49 # include <i18n.h>
50
51 extern char *Mrs;
52 extern int Domrs;
53
54 static char Mstr[RESPSIZE];
55 static char *getresp __PR((char *repstr, char *result));
56 static char *getcomments __PR((void));
57
58
59 void
dohist(file)60 dohist(file)
61 char *file;
62 {
63 char line[VBUF_SIZE];
64 int doprmt;
65 register char *p;
66 FILE *in;
67 extern char *Comments;
68
69 /*
70 * Quick and dirty way to find whether VALFLAG is set.
71 */
72 in = xfopen(file, O_RDONLY|O_BINARY);
73 #ifdef USE_SETVBUF
74 setvbuf(in, NULL, _IOFBF, VBUF_SIZE);
75 #endif
76 while ((p = fgets(line,sizeof(line),in)) != NULL)
77 if (line[0] == CTLCHAR && line[1] == EUSERNAM)
78 break;
79 if (p != NULL) {
80 while ((p = fgets(line,sizeof(line),in)) != NULL)
81 if (line[3] == VALFLAG && line[1] == FLAG && line[0] == CTLCHAR)
82 break;
83 else if (line[1] == BUSERTXT && line[0] == CTLCHAR)
84 break;
85 if (p != NULL && line[1] == FLAG) {
86 Domrs++;
87 }
88 }
89 (void) fclose(in);
90
91 doprmt = 0;
92 if (isatty(0) == 1)
93 doprmt++;
94 if (Domrs && !Mrs) {
95 if (doprmt)
96 printf(NOGETTEXT("MRs? "));
97 Mrs = getresp(" ",Mstr);
98 }
99 if (Domrs)
100 mrfixup();
101 if (!Comments) {
102 if (doprmt)
103 printf(gettext("comments? "));
104 Comments = getcomments();
105 }
106 }
107
108
109 static char *
getresp(repstr,result)110 getresp(repstr,result)
111 char *repstr;
112 char *result;
113 {
114 char line[MAXLINE]; /* Line length for typed in MR numbers */
115 register int done, sz;
116 register char *p;
117 extern char had_standinp;
118
119 result[0] = 0;
120 done = 0;
121 /*
122 save old fatal flag values and change to
123 values inside ()
124 */
125 FSAVE(FTLEXIT | FTLMSG | FTLCLN);
126 if ((had_standinp && (!HADY || (Domrs && !HADM)))) {
127 Ffile = 0;
128 fatal(gettext("standard input specified w/o -y and/or -m keyletter (de16)"));
129 }
130 /*
131 restore the old flag values and process if above
132 conditions were not met
133 */
134 FRSTR();
135 sz = sizeof(line) - size(repstr);
136 while (!done && fgets(line,sz,stdin) != NULL) {
137 p = strend(line);
138 if (*--p == '\n') {
139 if (*--p == '\\') {
140 copy(repstr,p);
141 }
142 else {
143 *++p = 0;
144 ++done;
145 }
146 }
147 else
148 fatal(gettext("line too long (co18)"));
149 if ((int) (size(line) + size(result)) > RESPSIZE)
150 fatal(gettext("response too long (co19)"));
151 strcat(result,line);
152 }
153 return(result);
154 }
155
156 static
157 char *
getcomments()158 getcomments()
159 {
160 char *buffer;
161 char *temp;
162 int c;
163 int bufsiz = BUFSIZ; /* Just an increment for malloc() */
164 int cnt = 0;
165 extern char had_standinp;
166
167 /*
168 save old fatal flag values and change to
169 values inside ()
170 */
171 FSAVE(FTLEXIT | FTLMSG | FTLCLN);
172 if ((had_standinp && (!HADY || (Domrs && !HADM)))) {
173 Ffile = 0;
174 fatal("standard input specified w/o -y and/or -m keyletter (de16)");
175 }
176 /*
177 restore the old flag values and process if above
178 conditions were not met
179 */
180 FRSTR();
181
182 buffer = (char *)malloc(bufsiz);
183 while ((c = getchar()) != EOF) {
184 if (c == '\n') {
185 if (buffer[cnt-1] == '\\') {
186 /*
187 * Just a continuation.
188 */
189 cnt -= 1;
190 } else {
191 /*
192 * End of input. It would be nice if EOT
193 * were something modern like ^D.
194 */
195 break;
196 }
197 }
198 buffer[cnt++] = c;
199 if (cnt == bufsiz-1) {
200 bufsiz += BUFSIZ;
201 temp = (char *)malloc(bufsiz);
202 strncpy(temp,buffer,cnt);
203 free(buffer);
204 buffer = temp;
205 }
206 }
207 if (buffer[cnt-1] == '\n')
208 buffer[cnt-1] = '\0';
209 else
210 buffer[cnt] = '\0';
211 return (buffer);
212 }
213
214 static char *Qarg[NVARGS];
215 char **Varg = Qarg;
216
217 int
valmrs(pkt,pgm)218 valmrs(pkt,pgm)
219 struct packet *pkt;
220 char *pgm;
221 {
222 register int i;
223 int st;
224 register char *p;
225
226 Varg[0] = pgm;
227 Varg[1] = auxf(pkt->p_file,'g');
228 if ((p = pkt->p_sflags[TYPEFLAG - 'a']) != NULL)
229 Varg[2] = p;
230 else
231 Varg[2] = Null;
232 if ((i = vfork()) < 0) {
233 #ifdef HAVE_VFORK
234 Fflags |= FTLVFORK;
235 #endif
236 fatal(gettext("cannot fork; try again (co20)"));
237 }
238 else if (i == 0) {
239 for (i = 4; i < 15; i++) {
240 #ifdef F_SETFD
241 fcntl(i, F_SETFD, 1);
242 #else
243 (void) close(i);
244 #endif
245 }
246 execvp(pgm,Varg);
247 _exit(1);
248 }
249 else {
250 wait(&st);
251 return(st);
252 }
253 /*NOTREACHED*/
254 return (0); /* fake for gcc */
255 }
256
257 # define LENMR 60
258
259 void
mrfixup()260 mrfixup()
261 {
262 register char **argv, *p, c;
263 char *ap;
264 unsigned int len;
265
266 argv = &Varg[VSTART];
267 p = Mrs;
268 NONBLANK(p);
269 for (ap = p; *p; p++) {
270 if (*p == ' ' || *p == '\t') {
271 if (argv >= &Varg[(NVARGS - 1)])
272 fatal(gettext("too many MRs (co21)"));
273 c = *p;
274 *p = 0;
275 if ((len = size(ap)) > LENMR)
276 fatal(gettext("MR number too long (co24)"));
277 *argv = stalloc(len);
278 copy(ap,*argv);
279 *p = c;
280 argv++;
281 NONBLANK(p);
282 ap = p;
283 }
284 }
285 --p;
286 if (*p != ' ' && *p != '\t') {
287 if ((len = size(ap)) > LENMR)
288 fatal(gettext("MR number too long (co24)"));
289 copy(ap,*argv++ = stalloc(len));
290 }
291 *argv = 0;
292 }
293
294
295 # define STBUFSZ 500
296
297 char *
stalloc(n)298 stalloc(n)
299 register unsigned int n;
300 {
301 static char stbuf[STBUFSZ];
302 static int stind = 0;
303 register char *p;
304
305 p = &stbuf[stind];
306 if (&p[n] >= &stbuf[STBUFSZ-1])
307 fatal(gettext("out of space (co22)"));
308 stind += n;
309 return(p);
310 }
311
312
313 char *
savecmt(p)314 savecmt(p)
315 register char *p;
316 {
317 register char *p1, *p2;
318 int ssize, nlcnt;
319
320 nlcnt = 0;
321 for (p1 = p; *p1; p1++)
322 if (*p1 == '\n')
323 nlcnt++;
324 /*
325 * ssize is length of line plus mush plus number of newlines
326 * times number of control characters per newline.
327 */
328 ssize = (strlen(p) + 4 + (nlcnt * 3)) & (~1);
329 p1 = fmalloc((unsigned) ssize);
330 p2 = p1;
331 /*CONSTCOND*/
332 while (1) {
333 while(*p && *p != '\n')
334 *p1++ = *p++;
335 if (*p == '\0') {
336 *p1 = '\0';
337 return(p2);
338 }
339 else {
340 p++;
341 *p1++ = '\n';
342 *p1++ = CTLCHAR;
343 *p1++ = COMMENTS;
344 *p1++ = ' ';
345 }
346 }
347 /*NOTREACHED*/
348 }
349
350 char *
get_Sccs_Comments()351 get_Sccs_Comments () {
352 return(getcomments());
353 }
354