xref: /illumos-gate/usr/src/cmd/ttymon/sttydefs.c (revision 7c478bd95313f5f23a4c958a745db2134aa0324)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate #include <stdio.h>
34*7c478bd9Sstevel@tonic-gate #include <unistd.h>
35*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
36*7c478bd9Sstevel@tonic-gate #include <errno.h>
37*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
38*7c478bd9Sstevel@tonic-gate #include <ctype.h>
39*7c478bd9Sstevel@tonic-gate #include <string.h>
40*7c478bd9Sstevel@tonic-gate #include <termio.h>
41*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
42*7c478bd9Sstevel@tonic-gate #include <signal.h>
43*7c478bd9Sstevel@tonic-gate #include <stdarg.h>
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate #include "tmstruct.h"
46*7c478bd9Sstevel@tonic-gate #include "ttymon.h"
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate static	int  nflg = 0;		/* -n seen */
49*7c478bd9Sstevel@tonic-gate static	int  iflg = 0;		/* -i seen */
50*7c478bd9Sstevel@tonic-gate static	int  fflg = 0;		/* -f seen */
51*7c478bd9Sstevel@tonic-gate static	int  lflg = 0;		/* -l seen */
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate struct  Gdef Gdef[MAXDEFS];	/* array to hold entries in /etc/ttydefs */
54*7c478bd9Sstevel@tonic-gate int	Ndefs = 0;		/* highest index to Gdef that was used   */
55*7c478bd9Sstevel@tonic-gate static	struct Gdef DEFAULT = {		/* default terminal settings	*/
56*7c478bd9Sstevel@tonic-gate 	"default",
57*7c478bd9Sstevel@tonic-gate 	"9600",
58*7c478bd9Sstevel@tonic-gate 	"9600 sane",
59*7c478bd9Sstevel@tonic-gate 	0,
60*7c478bd9Sstevel@tonic-gate 	/*
61*7c478bd9Sstevel@tonic-gate 	 * next label is set to 4800 so we can start searching ttydefs.
62*7c478bd9Sstevel@tonic-gate 	 * if 4800 is not in ttydefs, we will loop back to use DEFAULT
63*7c478bd9Sstevel@tonic-gate 	 */
64*7c478bd9Sstevel@tonic-gate 	"4800"
65*7c478bd9Sstevel@tonic-gate };
66*7c478bd9Sstevel@tonic-gate 
67*7c478bd9Sstevel@tonic-gate 
68*7c478bd9Sstevel@tonic-gate static	void	usage();
69*7c478bd9Sstevel@tonic-gate static	void	check_ref();
70*7c478bd9Sstevel@tonic-gate static	void	add_entry();
71*7c478bd9Sstevel@tonic-gate static	void	remove_entry();
72*7c478bd9Sstevel@tonic-gate static	int	copy_file();
73*7c478bd9Sstevel@tonic-gate static	int	verify();
74*7c478bd9Sstevel@tonic-gate static	FILE	*open_temp();
75*7c478bd9Sstevel@tonic-gate extern  void	read_ttydefs();
76*7c478bd9Sstevel@tonic-gate extern  int	check_version();
77*7c478bd9Sstevel@tonic-gate extern  int	find_label();
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate /*
80*7c478bd9Sstevel@tonic-gate  *	sttydefs - add, remove or check entries in /etc/ttydefs
81*7c478bd9Sstevel@tonic-gate  *
82*7c478bd9Sstevel@tonic-gate  *	Usage:	   sttydefs -a ttylabel [-n nextlabel] [-i initail-flags]
83*7c478bd9Sstevel@tonic-gate  *			    [-f final-flags] [-b]
84*7c478bd9Sstevel@tonic-gate  *		   sttydefs -r ttylabel
85*7c478bd9Sstevel@tonic-gate  *		   sttydefs -l [ttylabel]
86*7c478bd9Sstevel@tonic-gate  *
87*7c478bd9Sstevel@tonic-gate  */
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate int
90*7c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
91*7c478bd9Sstevel@tonic-gate {
92*7c478bd9Sstevel@tonic-gate 	int c;			/* option letter */
93*7c478bd9Sstevel@tonic-gate 	int errflg = 0;		/* error indicator */
94*7c478bd9Sstevel@tonic-gate 	int  aflg = 0;		/* -a seen */
95*7c478bd9Sstevel@tonic-gate 	int  bflg = 0;		/* -b seen */
96*7c478bd9Sstevel@tonic-gate 	int	ret;
97*7c478bd9Sstevel@tonic-gate #ifdef __STDC__
98*7c478bd9Sstevel@tonic-gate 	const
99*7c478bd9Sstevel@tonic-gate #endif
100*7c478bd9Sstevel@tonic-gate 	char	*argtmp;
101*7c478bd9Sstevel@tonic-gate 	char	*nextlabel;
102*7c478bd9Sstevel@tonic-gate 	struct Gdef ttydef, *ptr;
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate 	extern	char	*optarg;
105*7c478bd9Sstevel@tonic-gate 	extern	int	optind;
106*7c478bd9Sstevel@tonic-gate 
107*7c478bd9Sstevel@tonic-gate 	if (argc == 1)
108*7c478bd9Sstevel@tonic-gate 		usage();
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate         /* Initialize ttydef structure */
111*7c478bd9Sstevel@tonic-gate         memset (&ttydef, 0, sizeof(ttydef));
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate 	ptr = &ttydef;
114*7c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "a:n:i:f:br:l")) != -1) {
115*7c478bd9Sstevel@tonic-gate 		switch (c) {
116*7c478bd9Sstevel@tonic-gate 		case 'a':
117*7c478bd9Sstevel@tonic-gate 			aflg = TRUE;
118*7c478bd9Sstevel@tonic-gate 			ptr->g_id = optarg;
119*7c478bd9Sstevel@tonic-gate 			break;
120*7c478bd9Sstevel@tonic-gate 		case 'n':
121*7c478bd9Sstevel@tonic-gate 			nflg = TRUE;
122*7c478bd9Sstevel@tonic-gate 			ptr->g_nextid = optarg;
123*7c478bd9Sstevel@tonic-gate 			break;
124*7c478bd9Sstevel@tonic-gate 		case 'i':
125*7c478bd9Sstevel@tonic-gate 			iflg = TRUE;
126*7c478bd9Sstevel@tonic-gate 			ptr->g_iflags = optarg;
127*7c478bd9Sstevel@tonic-gate 			break;
128*7c478bd9Sstevel@tonic-gate 		case 'f':
129*7c478bd9Sstevel@tonic-gate 			fflg = TRUE;
130*7c478bd9Sstevel@tonic-gate 			ptr->g_fflags = optarg;
131*7c478bd9Sstevel@tonic-gate 			break;
132*7c478bd9Sstevel@tonic-gate 		case 'b':
133*7c478bd9Sstevel@tonic-gate 			bflg = TRUE;
134*7c478bd9Sstevel@tonic-gate 			ptr->g_autobaud |= A_FLAG;
135*7c478bd9Sstevel@tonic-gate 			break;
136*7c478bd9Sstevel@tonic-gate 		case 'r':
137*7c478bd9Sstevel@tonic-gate 			if ((argc > 3) || (optind < argc))
138*7c478bd9Sstevel@tonic-gate 				usage();
139*7c478bd9Sstevel@tonic-gate 			remove_entry(optarg);
140*7c478bd9Sstevel@tonic-gate 			break;
141*7c478bd9Sstevel@tonic-gate 		case 'l':
142*7c478bd9Sstevel@tonic-gate 			lflg = TRUE;
143*7c478bd9Sstevel@tonic-gate 			if (argc > 3)
144*7c478bd9Sstevel@tonic-gate 				usage();
145*7c478bd9Sstevel@tonic-gate 			if ((ret = check_version(TTYDEFS_VERS, TTYDEFS)) != 0) {
146*7c478bd9Sstevel@tonic-gate 				if (ret != 2) {
147*7c478bd9Sstevel@tonic-gate 					(void)fprintf(stderr, "%s version number is incorrect or missing.\n",TTYDEFS);
148*7c478bd9Sstevel@tonic-gate 					exit(1);
149*7c478bd9Sstevel@tonic-gate 				}
150*7c478bd9Sstevel@tonic-gate 				(void)fprintf(stderr, "sttydefs: can't open %s.\n",TTYDEFS);
151*7c478bd9Sstevel@tonic-gate 				exit(1);
152*7c478bd9Sstevel@tonic-gate 			}
153*7c478bd9Sstevel@tonic-gate 			if (argv[optind] == NULL) {
154*7c478bd9Sstevel@tonic-gate 				read_ttydefs(NULL,TRUE);
155*7c478bd9Sstevel@tonic-gate 				printf("\n");
156*7c478bd9Sstevel@tonic-gate 				check_ref();
157*7c478bd9Sstevel@tonic-gate 			}
158*7c478bd9Sstevel@tonic-gate 			else {
159*7c478bd9Sstevel@tonic-gate 				if (argc == 3) { /* -l ttylabel */
160*7c478bd9Sstevel@tonic-gate 					if (verify(argv[optind],0) != 0) {
161*7c478bd9Sstevel@tonic-gate 						errflg++;
162*7c478bd9Sstevel@tonic-gate 						break;
163*7c478bd9Sstevel@tonic-gate 					}
164*7c478bd9Sstevel@tonic-gate 					argtmp = argv[optind];
165*7c478bd9Sstevel@tonic-gate 				}
166*7c478bd9Sstevel@tonic-gate 				else { /* -lttylabel */
167*7c478bd9Sstevel@tonic-gate 					argtmp = argv[optind]+2;
168*7c478bd9Sstevel@tonic-gate 				}
169*7c478bd9Sstevel@tonic-gate 				read_ttydefs(argtmp,TRUE);
170*7c478bd9Sstevel@tonic-gate 				if (Ndefs == 0) {
171*7c478bd9Sstevel@tonic-gate 					(void)fprintf(stderr,
172*7c478bd9Sstevel@tonic-gate 					"ttylabel <%s> not found.\n", argtmp);
173*7c478bd9Sstevel@tonic-gate 					exit(1);
174*7c478bd9Sstevel@tonic-gate 				}
175*7c478bd9Sstevel@tonic-gate 				nextlabel = Gdef[--Ndefs].g_nextid;
176*7c478bd9Sstevel@tonic-gate 				Ndefs = 0;
177*7c478bd9Sstevel@tonic-gate 				read_ttydefs(nextlabel,FALSE);
178*7c478bd9Sstevel@tonic-gate 				if (Ndefs == 0) {
179*7c478bd9Sstevel@tonic-gate 					(void)printf("\nWarning -- nextlabel <%s> of <%s> does not reference any existing ttylabel.\n",
180*7c478bd9Sstevel@tonic-gate 					nextlabel, argtmp);
181*7c478bd9Sstevel@tonic-gate 				}
182*7c478bd9Sstevel@tonic-gate 			}
183*7c478bd9Sstevel@tonic-gate 			exit(0);
184*7c478bd9Sstevel@tonic-gate 			break;		/*NOTREACHED*/
185*7c478bd9Sstevel@tonic-gate 		case '?':
186*7c478bd9Sstevel@tonic-gate 			errflg++;
187*7c478bd9Sstevel@tonic-gate 			break;
188*7c478bd9Sstevel@tonic-gate 		} /* end switch */
189*7c478bd9Sstevel@tonic-gate 		if (errflg)
190*7c478bd9Sstevel@tonic-gate 			usage();
191*7c478bd9Sstevel@tonic-gate 	} /* end while */
192*7c478bd9Sstevel@tonic-gate 	if (optind < argc)
193*7c478bd9Sstevel@tonic-gate 		usage();
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate 	if (aflg) {
196*7c478bd9Sstevel@tonic-gate 		add_entry(ptr); 	/* never return */
197*7c478bd9Sstevel@tonic-gate 	}
198*7c478bd9Sstevel@tonic-gate 	if ((iflg) || (fflg) || (bflg) || (nflg))
199*7c478bd9Sstevel@tonic-gate 		usage();
200*7c478bd9Sstevel@tonic-gate 	return (0);
201*7c478bd9Sstevel@tonic-gate }
202*7c478bd9Sstevel@tonic-gate 
203*7c478bd9Sstevel@tonic-gate /*
204*7c478bd9Sstevel@tonic-gate  *	verify	- to check if arg is valid
205*7c478bd9Sstevel@tonic-gate  *		- i.e. arg cannot start with '-' and
206*7c478bd9Sstevel@tonic-gate  *		  arg must not longer than maxarglen
207*7c478bd9Sstevel@tonic-gate  *		- return 0 if ok. Otherwise return -1
208*7c478bd9Sstevel@tonic-gate  */
209*7c478bd9Sstevel@tonic-gate static	int
210*7c478bd9Sstevel@tonic-gate verify(arg,maxarglen)
211*7c478bd9Sstevel@tonic-gate char	*arg;
212*7c478bd9Sstevel@tonic-gate int	maxarglen;
213*7c478bd9Sstevel@tonic-gate {
214*7c478bd9Sstevel@tonic-gate 	if (*arg == '-') {
215*7c478bd9Sstevel@tonic-gate 		(void)fprintf(stderr, "Invalid argument -- %s.\n", arg);
216*7c478bd9Sstevel@tonic-gate 		return(-1);
217*7c478bd9Sstevel@tonic-gate 	}
218*7c478bd9Sstevel@tonic-gate 	if ((maxarglen) && ((int)strlen(arg) > maxarglen)) {
219*7c478bd9Sstevel@tonic-gate 		arg[maxarglen] = '\0';
220*7c478bd9Sstevel@tonic-gate 		(void)fprintf(stderr,"string too long, truncated to %s.\n",arg);
221*7c478bd9Sstevel@tonic-gate 		return(-1);
222*7c478bd9Sstevel@tonic-gate 	}
223*7c478bd9Sstevel@tonic-gate 	return(0);
224*7c478bd9Sstevel@tonic-gate }
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate /*
227*7c478bd9Sstevel@tonic-gate  * usage - print out a usage message
228*7c478bd9Sstevel@tonic-gate  */
229*7c478bd9Sstevel@tonic-gate 
230*7c478bd9Sstevel@tonic-gate static	void
231*7c478bd9Sstevel@tonic-gate usage()
232*7c478bd9Sstevel@tonic-gate {
233*7c478bd9Sstevel@tonic-gate 	(void)fprintf(stderr, "Usage:\tsttydefs -a ttylabel [-n nextlabel] [-i initial-flags]\n\t\t [-f final-flags] [-b]\n");
234*7c478bd9Sstevel@tonic-gate 	(void)fprintf(stderr, "\tsttydefs -r ttylabel\n");
235*7c478bd9Sstevel@tonic-gate 	(void)fprintf(stderr, "\tsttydefs -l [ttylabel]\n");
236*7c478bd9Sstevel@tonic-gate 	exit(2);
237*7c478bd9Sstevel@tonic-gate }
238*7c478bd9Sstevel@tonic-gate 
239*7c478bd9Sstevel@tonic-gate /*
240*7c478bd9Sstevel@tonic-gate  *	add_entry - add an entry to /etc/ttydefs
241*7c478bd9Sstevel@tonic-gate  */
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate static	void
244*7c478bd9Sstevel@tonic-gate add_entry(ttydef)
245*7c478bd9Sstevel@tonic-gate struct Gdef *ttydef;
246*7c478bd9Sstevel@tonic-gate {
247*7c478bd9Sstevel@tonic-gate 	FILE *fp;
248*7c478bd9Sstevel@tonic-gate 	int	errflg = 0;
249*7c478bd9Sstevel@tonic-gate 	char tbuf[BUFSIZ], *tp;
250*7c478bd9Sstevel@tonic-gate 	int  add_version = FALSE;
251*7c478bd9Sstevel@tonic-gate 	extern	int	check_flags();
252*7c478bd9Sstevel@tonic-gate 
253*7c478bd9Sstevel@tonic-gate 	if (getuid()) {
254*7c478bd9Sstevel@tonic-gate 		(void)fprintf(stderr, "User not privileged for operation.\n");
255*7c478bd9Sstevel@tonic-gate 		exit(1);
256*7c478bd9Sstevel@tonic-gate 	}
257*7c478bd9Sstevel@tonic-gate 	tp = tbuf;
258*7c478bd9Sstevel@tonic-gate 	*tp = '\0';
259*7c478bd9Sstevel@tonic-gate 	if ((fp = fopen(TTYDEFS, "r")) != NULL) {
260*7c478bd9Sstevel@tonic-gate 		if (check_version(TTYDEFS_VERS, TTYDEFS) != 0) {
261*7c478bd9Sstevel@tonic-gate 			(void)fprintf(stderr,
262*7c478bd9Sstevel@tonic-gate 			"%s version number is incorrect or missing.\n",TTYDEFS);
263*7c478bd9Sstevel@tonic-gate 			exit(1);
264*7c478bd9Sstevel@tonic-gate 		}
265*7c478bd9Sstevel@tonic-gate 		if (find_label(fp,ttydef->g_id)) {
266*7c478bd9Sstevel@tonic-gate 			(void)fclose(fp);
267*7c478bd9Sstevel@tonic-gate 			(void)fprintf(stderr,
268*7c478bd9Sstevel@tonic-gate 			"Invalid request -- ttylabel <%s> already exists.\n",
269*7c478bd9Sstevel@tonic-gate 			ttydef->g_id);
270*7c478bd9Sstevel@tonic-gate 			exit(1);
271*7c478bd9Sstevel@tonic-gate 		}
272*7c478bd9Sstevel@tonic-gate 		(void)fclose(fp);
273*7c478bd9Sstevel@tonic-gate 	}
274*7c478bd9Sstevel@tonic-gate 	else  {
275*7c478bd9Sstevel@tonic-gate 		add_version = TRUE;
276*7c478bd9Sstevel@tonic-gate 	}
277*7c478bd9Sstevel@tonic-gate 	if ((fp = fopen(TTYDEFS, "a+")) == NULL) {
278*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "Could not open \"%s\": %s", TTYDEFS,
279*7c478bd9Sstevel@tonic-gate 		    strerror(errno));
280*7c478bd9Sstevel@tonic-gate 		exit(1);
281*7c478bd9Sstevel@tonic-gate 	}
282*7c478bd9Sstevel@tonic-gate 
283*7c478bd9Sstevel@tonic-gate 	if (add_version) {
284*7c478bd9Sstevel@tonic-gate 	   (void)fprintf(fp,"# VERSION=%d\n", TTYDEFS_VERS);
285*7c478bd9Sstevel@tonic-gate 	}
286*7c478bd9Sstevel@tonic-gate 
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate 	/* if optional fields are not provided, set to default */
289*7c478bd9Sstevel@tonic-gate 	if (!iflg)
290*7c478bd9Sstevel@tonic-gate 		ttydef->g_iflags = DEFAULT.g_iflags;
291*7c478bd9Sstevel@tonic-gate 	else
292*7c478bd9Sstevel@tonic-gate 		if (check_flags(ttydef->g_iflags) != 0 )
293*7c478bd9Sstevel@tonic-gate 			errflg++;
294*7c478bd9Sstevel@tonic-gate 	if (!fflg)
295*7c478bd9Sstevel@tonic-gate 		ttydef->g_fflags = DEFAULT.g_fflags;
296*7c478bd9Sstevel@tonic-gate 	else
297*7c478bd9Sstevel@tonic-gate 		if (check_flags(ttydef->g_fflags) != 0 )
298*7c478bd9Sstevel@tonic-gate 			errflg++;
299*7c478bd9Sstevel@tonic-gate 	if (errflg)
300*7c478bd9Sstevel@tonic-gate 		exit(1);
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate 	if (!nflg)
303*7c478bd9Sstevel@tonic-gate 		ttydef->g_nextid = ttydef->g_id;
304*7c478bd9Sstevel@tonic-gate 
305*7c478bd9Sstevel@tonic-gate 	if (ttydef->g_autobaud & A_FLAG)  {
306*7c478bd9Sstevel@tonic-gate 	   (void)fprintf(fp,"%s:%s:%s:A:%s\n", ttydef->g_id, ttydef->g_iflags,
307*7c478bd9Sstevel@tonic-gate 		ttydef->g_fflags, ttydef->g_nextid);
308*7c478bd9Sstevel@tonic-gate 	}
309*7c478bd9Sstevel@tonic-gate 	else {
310*7c478bd9Sstevel@tonic-gate 	   (void)fprintf(fp,"%s:%s:%s::%s\n", ttydef->g_id, ttydef->g_iflags,
311*7c478bd9Sstevel@tonic-gate 		ttydef->g_fflags, ttydef->g_nextid);
312*7c478bd9Sstevel@tonic-gate 	}
313*7c478bd9Sstevel@tonic-gate 	(void)fclose(fp);
314*7c478bd9Sstevel@tonic-gate 	exit(0);
315*7c478bd9Sstevel@tonic-gate }
316*7c478bd9Sstevel@tonic-gate 
317*7c478bd9Sstevel@tonic-gate static	void
318*7c478bd9Sstevel@tonic-gate remove_entry(ttylabel)
319*7c478bd9Sstevel@tonic-gate char	*ttylabel;
320*7c478bd9Sstevel@tonic-gate {
321*7c478bd9Sstevel@tonic-gate 	FILE *tfp;		/* file pointer for temp file */
322*7c478bd9Sstevel@tonic-gate 	int line;		/* line number entry is on */
323*7c478bd9Sstevel@tonic-gate 	FILE *fp;		/* scratch file pointer */
324*7c478bd9Sstevel@tonic-gate 	char *tname = "/etc/.ttydefs";
325*7c478bd9Sstevel@tonic-gate 
326*7c478bd9Sstevel@tonic-gate 	if (getuid()) {
327*7c478bd9Sstevel@tonic-gate 		(void)fprintf(stderr, "User not privileged for operation.\n");
328*7c478bd9Sstevel@tonic-gate 		exit(1);
329*7c478bd9Sstevel@tonic-gate 	}
330*7c478bd9Sstevel@tonic-gate 	fp = fopen(TTYDEFS, "r");
331*7c478bd9Sstevel@tonic-gate 	if (fp == NULL) {
332*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "Could not open \"%s\": %s", TTYDEFS,
333*7c478bd9Sstevel@tonic-gate 		    strerror(errno));
334*7c478bd9Sstevel@tonic-gate 		exit(1);
335*7c478bd9Sstevel@tonic-gate 	}
336*7c478bd9Sstevel@tonic-gate 	if (check_version(TTYDEFS_VERS, TTYDEFS) != 0) {
337*7c478bd9Sstevel@tonic-gate 		(void)fprintf(stderr,
338*7c478bd9Sstevel@tonic-gate 			"%s version number is incorrect or missing.\n",TTYDEFS);
339*7c478bd9Sstevel@tonic-gate 		exit(1);
340*7c478bd9Sstevel@tonic-gate 	}
341*7c478bd9Sstevel@tonic-gate 	if ((line = find_label(fp, ttylabel)) == 0) {
342*7c478bd9Sstevel@tonic-gate 		(void)fprintf(stderr,
343*7c478bd9Sstevel@tonic-gate 		"Invalid request, ttylabel <%s> does not exist.\n", ttylabel);
344*7c478bd9Sstevel@tonic-gate 		exit(1);
345*7c478bd9Sstevel@tonic-gate 	}
346*7c478bd9Sstevel@tonic-gate 	tfp = open_temp(tname);
347*7c478bd9Sstevel@tonic-gate 	if (line != 1)
348*7c478bd9Sstevel@tonic-gate 		if (copy_file(fp, tfp, 1, line - 1)) {
349*7c478bd9Sstevel@tonic-gate 			(void)fprintf(stderr,"Error accessing temp file.\n");
350*7c478bd9Sstevel@tonic-gate 			exit(1);
351*7c478bd9Sstevel@tonic-gate 		}
352*7c478bd9Sstevel@tonic-gate 	if (copy_file(fp, tfp, line + 1, -1)) {
353*7c478bd9Sstevel@tonic-gate 		(void)fprintf(stderr,"Error accessing temp file.\n");
354*7c478bd9Sstevel@tonic-gate 		exit(1);
355*7c478bd9Sstevel@tonic-gate 	}
356*7c478bd9Sstevel@tonic-gate 	(void)fclose(fp);
357*7c478bd9Sstevel@tonic-gate 	if (fclose(tfp) == EOF) {
358*7c478bd9Sstevel@tonic-gate 		(void)unlink(tname);
359*7c478bd9Sstevel@tonic-gate 		(void)fprintf(stderr,"Error closing temp file.\n");
360*7c478bd9Sstevel@tonic-gate 		exit(1);
361*7c478bd9Sstevel@tonic-gate 	}
362*7c478bd9Sstevel@tonic-gate 	(void)unlink(TTYDEFS);
363*7c478bd9Sstevel@tonic-gate 	if (rename(tname, TTYDEFS) != 0 ) {
364*7c478bd9Sstevel@tonic-gate 		perror("Rename failed");
365*7c478bd9Sstevel@tonic-gate 		(void)unlink(tname);
366*7c478bd9Sstevel@tonic-gate 		exit(1);
367*7c478bd9Sstevel@tonic-gate 	}
368*7c478bd9Sstevel@tonic-gate 	exit(0);
369*7c478bd9Sstevel@tonic-gate }
370*7c478bd9Sstevel@tonic-gate 
371*7c478bd9Sstevel@tonic-gate /*
372*7c478bd9Sstevel@tonic-gate  * open_temp - open up a temp file
373*7c478bd9Sstevel@tonic-gate  *
374*7c478bd9Sstevel@tonic-gate  *	args:	tname - temp file name
375*7c478bd9Sstevel@tonic-gate  */
376*7c478bd9Sstevel@tonic-gate 
377*7c478bd9Sstevel@tonic-gate static	FILE *
378*7c478bd9Sstevel@tonic-gate open_temp(tname)
379*7c478bd9Sstevel@tonic-gate char *tname;
380*7c478bd9Sstevel@tonic-gate {
381*7c478bd9Sstevel@tonic-gate 	FILE *fp;			/* fp associated with tname */
382*7c478bd9Sstevel@tonic-gate 	struct sigaction sigact;	/* for signal handling */
383*7c478bd9Sstevel@tonic-gate 
384*7c478bd9Sstevel@tonic-gate 	sigact.sa_flags = 0;
385*7c478bd9Sstevel@tonic-gate 	sigact.sa_handler = SIG_IGN;
386*7c478bd9Sstevel@tonic-gate 	(void) sigemptyset(&sigact.sa_mask);
387*7c478bd9Sstevel@tonic-gate 	(void) sigaddset(&sigact.sa_mask, SIGHUP);
388*7c478bd9Sstevel@tonic-gate 	(void) sigaddset(&sigact.sa_mask, SIGINT);
389*7c478bd9Sstevel@tonic-gate 	(void) sigaddset(&sigact.sa_mask, SIGQUIT);
390*7c478bd9Sstevel@tonic-gate 	(void) sigaction(SIGHUP, &sigact, NULL);
391*7c478bd9Sstevel@tonic-gate 	(void) sigaction(SIGINT, &sigact, NULL);
392*7c478bd9Sstevel@tonic-gate 	(void) sigaction(SIGQUIT, &sigact, NULL);
393*7c478bd9Sstevel@tonic-gate 	(void)umask(0333);
394*7c478bd9Sstevel@tonic-gate 	if (access(tname, 0) != -1) {
395*7c478bd9Sstevel@tonic-gate 		(void)fprintf(stderr,"tempfile busy; try again later.\n");
396*7c478bd9Sstevel@tonic-gate 		exit(1);
397*7c478bd9Sstevel@tonic-gate 	}
398*7c478bd9Sstevel@tonic-gate 	fp = fopen(tname, "w");
399*7c478bd9Sstevel@tonic-gate 	if (fp == NULL) {
400*7c478bd9Sstevel@tonic-gate 		perror("Cannot create tempfile");
401*7c478bd9Sstevel@tonic-gate 		exit(1);
402*7c478bd9Sstevel@tonic-gate 	}
403*7c478bd9Sstevel@tonic-gate 	return(fp);
404*7c478bd9Sstevel@tonic-gate }
405*7c478bd9Sstevel@tonic-gate 
406*7c478bd9Sstevel@tonic-gate /*
407*7c478bd9Sstevel@tonic-gate  * copy_file - copy information from one file to another, return 0 on
408*7c478bd9Sstevel@tonic-gate  *	success, -1 on failure
409*7c478bd9Sstevel@tonic-gate  *
410*7c478bd9Sstevel@tonic-gate  *	args:	fp - source file's file pointer
411*7c478bd9Sstevel@tonic-gate  *		tfp - destination file's file pointer
412*7c478bd9Sstevel@tonic-gate  *		start - starting line number
413*7c478bd9Sstevel@tonic-gate  *		finish - ending line number (-1 indicates entire file)
414*7c478bd9Sstevel@tonic-gate  */
415*7c478bd9Sstevel@tonic-gate 
416*7c478bd9Sstevel@tonic-gate 
417*7c478bd9Sstevel@tonic-gate static	int
418*7c478bd9Sstevel@tonic-gate copy_file(fp, tfp, start, finish)
419*7c478bd9Sstevel@tonic-gate FILE *fp;
420*7c478bd9Sstevel@tonic-gate FILE *tfp;
421*7c478bd9Sstevel@tonic-gate register int start;
422*7c478bd9Sstevel@tonic-gate register int finish;
423*7c478bd9Sstevel@tonic-gate {
424*7c478bd9Sstevel@tonic-gate 	register int i;		/* loop variable */
425*7c478bd9Sstevel@tonic-gate 	char dummy[BUFSIZ];	/* scratch buffer */
426*7c478bd9Sstevel@tonic-gate 
427*7c478bd9Sstevel@tonic-gate /*
428*7c478bd9Sstevel@tonic-gate  * always start from the beginning because line numbers are absolute
429*7c478bd9Sstevel@tonic-gate  */
430*7c478bd9Sstevel@tonic-gate 
431*7c478bd9Sstevel@tonic-gate 	rewind(fp);
432*7c478bd9Sstevel@tonic-gate 
433*7c478bd9Sstevel@tonic-gate /*
434*7c478bd9Sstevel@tonic-gate  * get to the starting point of interest
435*7c478bd9Sstevel@tonic-gate  */
436*7c478bd9Sstevel@tonic-gate 
437*7c478bd9Sstevel@tonic-gate 	if (start != 1) {
438*7c478bd9Sstevel@tonic-gate 		for (i = 1; i < start; i++)
439*7c478bd9Sstevel@tonic-gate 			if (!fgets(dummy, BUFSIZ, fp))
440*7c478bd9Sstevel@tonic-gate 				return(-1);
441*7c478bd9Sstevel@tonic-gate 	}
442*7c478bd9Sstevel@tonic-gate 
443*7c478bd9Sstevel@tonic-gate /*
444*7c478bd9Sstevel@tonic-gate  * copy as much as was requested
445*7c478bd9Sstevel@tonic-gate  */
446*7c478bd9Sstevel@tonic-gate 
447*7c478bd9Sstevel@tonic-gate 	if (finish != -1) {
448*7c478bd9Sstevel@tonic-gate 		for (i = start; i <= finish; i++) {
449*7c478bd9Sstevel@tonic-gate 			if (!fgets(dummy, BUFSIZ, fp))
450*7c478bd9Sstevel@tonic-gate 				return(-1);
451*7c478bd9Sstevel@tonic-gate 			if (fputs(dummy, tfp) == EOF)
452*7c478bd9Sstevel@tonic-gate 				return(-1);
453*7c478bd9Sstevel@tonic-gate 		}
454*7c478bd9Sstevel@tonic-gate 	}
455*7c478bd9Sstevel@tonic-gate 	else {
456*7c478bd9Sstevel@tonic-gate 		for (;;) {
457*7c478bd9Sstevel@tonic-gate 			if (fgets(dummy, BUFSIZ, fp) == NULL) {
458*7c478bd9Sstevel@tonic-gate 				if (feof(fp))
459*7c478bd9Sstevel@tonic-gate 					break;
460*7c478bd9Sstevel@tonic-gate 				else
461*7c478bd9Sstevel@tonic-gate 					return(-1);
462*7c478bd9Sstevel@tonic-gate 			}
463*7c478bd9Sstevel@tonic-gate 			if (fputs(dummy, tfp) == EOF)
464*7c478bd9Sstevel@tonic-gate 				return(-1);
465*7c478bd9Sstevel@tonic-gate 		}
466*7c478bd9Sstevel@tonic-gate 	}
467*7c478bd9Sstevel@tonic-gate 	return(0);
468*7c478bd9Sstevel@tonic-gate }
469*7c478bd9Sstevel@tonic-gate 
470*7c478bd9Sstevel@tonic-gate /*
471*7c478bd9Sstevel@tonic-gate  *	check_ref	- to check if nextlabel are referencing
472*7c478bd9Sstevel@tonic-gate  *			  existing ttylabel
473*7c478bd9Sstevel@tonic-gate  */
474*7c478bd9Sstevel@tonic-gate static	void
475*7c478bd9Sstevel@tonic-gate check_ref()
476*7c478bd9Sstevel@tonic-gate {
477*7c478bd9Sstevel@tonic-gate 	int	i;
478*7c478bd9Sstevel@tonic-gate 	struct	Gdef	*np;
479*7c478bd9Sstevel@tonic-gate 	extern	struct	Gdef	*find_def();
480*7c478bd9Sstevel@tonic-gate 	np = &Gdef[0];
481*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < Ndefs; i++, np++) {
482*7c478bd9Sstevel@tonic-gate 		if (find_def(np->g_nextid) == NULL) {
483*7c478bd9Sstevel@tonic-gate 			(void)printf("Warning -- nextlabel <%s> of <%s> does not reference any existing ttylabel.\n",
484*7c478bd9Sstevel@tonic-gate 			np->g_nextid, np->g_id);
485*7c478bd9Sstevel@tonic-gate 		}
486*7c478bd9Sstevel@tonic-gate 	}
487*7c478bd9Sstevel@tonic-gate 	return;
488*7c478bd9Sstevel@tonic-gate }
489*7c478bd9Sstevel@tonic-gate 
490*7c478bd9Sstevel@tonic-gate /*
491*7c478bd9Sstevel@tonic-gate  *	log	- print a message to stdout
492*7c478bd9Sstevel@tonic-gate  */
493*7c478bd9Sstevel@tonic-gate 
494*7c478bd9Sstevel@tonic-gate void
495*7c478bd9Sstevel@tonic-gate log(const char *msg, ...)
496*7c478bd9Sstevel@tonic-gate {
497*7c478bd9Sstevel@tonic-gate 	va_list ap;
498*7c478bd9Sstevel@tonic-gate 	if (lflg) {
499*7c478bd9Sstevel@tonic-gate 		va_start(ap, msg);
500*7c478bd9Sstevel@tonic-gate 		(void) vprintf(msg, ap);
501*7c478bd9Sstevel@tonic-gate 		va_end(ap);
502*7c478bd9Sstevel@tonic-gate 		(void) printf("\n");
503*7c478bd9Sstevel@tonic-gate 	} else {
504*7c478bd9Sstevel@tonic-gate 		va_start(ap, msg);
505*7c478bd9Sstevel@tonic-gate 		(void) vfprintf(stderr, msg, ap);
506*7c478bd9Sstevel@tonic-gate 		va_end(ap);
507*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,"\n");
508*7c478bd9Sstevel@tonic-gate 	}
509*7c478bd9Sstevel@tonic-gate }
510