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