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