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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 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. 13 * 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] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1996, by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * tput.c 31 * 32 * Copyright 1990, 1994 by Mortice Kern Systems Inc. All rights reserved. 33 * 34 * PORTABILITY: 35 * SVID 3 - fully 36 * POSIX.2a UPE - needs clarification between SVID 3 exit statues. 37 * In particular exit 1 and 4 for string capnames. 38 * not in XPG 3 39 * 40 * SYNOPSIS: 41 * tput [-T<term>] capname [parm1..parm9] 42 * tput [-T<term>] -S 43 * 44 * DESCRIPTION: 45 * tput lets you change your terminal's characteristics. The capname 46 * argument indicates how you want to change the characteristics. 47 * Some special capnames are: 48 * 49 * clear clear the screen 50 * init initialize terminal in an implemenation-defined way 51 * reset reset terminal in an implemenation-defined way 52 * longname print the full name of the ternminal (SVID) 53 * 54 * Other capnames are supported and may take from 0 to 9 parameters. A 55 * list of them can be found in the SVID 3, vol 3. (SVID) 56 * 57 * tput does its work by outputting approriate character sequences to the 58 * standard output. These character sequences are terminal-specific. If 59 * you specify -T <type>, tput assumes that your terminal has the 60 * specified type and will issue sequences appropriate to that terminal. 61 * 62 * If you do not specify -T, tput looks for an environment variable 63 * named TERM. If TERM exists, its value is assumed to give the terminal 64 * type. If TERM does not exist, tput assumes a default terminal type. 65 * 66 * The -S option allows more than one capability per invocation of tput. 67 * The capabilities must be passed to tput from the standard input instead 68 * of the comamnd line. Only one capname is allowed per line. 69 * 70 * EXIT STATUS 71 * tput may return the following status values: 72 * 73 * 0 Either a boolean capname is set true or a string capname was 74 * successfully written to the terminal. 75 * 76 * 1 No error message is printed. Returned if a boolean capname is 77 * false or a string capname is not defined for the terminal.(SVID) 78 * 79 * 2 Usage error. 80 * 81 * 3 Unknown terminal <term> or no terminfo database. 82 * 83 * 4 Unknown terminfo capability <capname>. 84 * 85 * >4 An error occured. 86 * 87 * 88 * NOTE 1: If the Caps file that describes the terminfo database changes 89 * then a new term.h will be required. See CURSES/tic related tools. 90 * 91 * NOTE 2: tput has knowledge about the TERMINAL structure. 92 */ 93 #ifdef M_RCSID 94 #ifndef lint 95 static char rcsID[] = "$Id: tput.c 1.28 1995/04/12 09:28:05 ross Exp $"; 96 #endif 97 #endif 98 99 #include <mks.h> 100 #include <curses.h> 101 #include <term.h> 102 #include <ctype.h> 103 #include <limits.h> 104 #include <stdarg.h> 105 #include <stdio.h> 106 #include <stdlib.h> 107 #include <string.h> 108 109 extern char *_cmdname; 110 111 112 /* Exit Status */ 113 #define SUCCESS 0 114 #define NOT_DEFINED 1 115 #define USAGE 2 116 #define BAD_TERMINAL 3 117 #define NOT_VALID 4 118 #define ERROR 5 119 120 static int S_flag = 0; 121 static char *term_name; 122 static char dumb_term[] = "dumb"; 123 static char usage_msg[] = m_textstr(4931, "\ 124 Usage: tput [-W] [-Tterm] capname [parm1..parm9]\n\ 125 tput [-W] [-Tterm] -S\n", "U"); 126 127 STATREF void build_argv ANSI((int *ac, char ***av)); 128 STATREF int do_tput ANSI((int _argc, char **_argv)); 129 STATREF void init ANSI((void)); 130 STATREF void reset ANSI((void)); 131 STATREF int usage ANSI((void)); 132 STATREF void err_msg ANSI((char *fmt, ...)); /* GENTEXT: err_msg */ 133 STATREF void cat ANSI((char *_Fn)); 134 135 /*f 136 * mainline for tput 137 */ 138 int 139 main(argc, argv) 140 int argc; 141 char **argv; 142 { 143 int opt; 144 int err_code; 145 setlocale(LC_ALL, ""); 146 _cmdname = m_cmdname(*argv); 147 if ((term_name = getenv("TERM")) == NULL) { 148 term_name = dumb_term; 149 } else { 150 term_name = m_strdup(term_name); 151 } 152 153 /* Default uses the terminfo database without modification. */ 154 use_env(0); 155 156 while ((opt = getopt(argc, argv, "ST:W")) != -1) { 157 switch (opt) { 158 case 'W': 159 /* Environment/window size are consulted and may 160 * alter the database entries for lines and columns. 161 */ 162 use_env(1); 163 break; 164 case 'S': 165 S_flag = 1; 166 break; 167 168 case 'T': 169 term_name = optarg; 170 break; 171 172 default: 173 return (usage()); 174 } 175 } 176 177 argc -= optind; 178 argv += optind; 179 180 if ((S_flag ^ (argc <= 0)) == 1) 181 return (usage()); 182 (void) setupterm(term_name, fileno(stdout), &err_code); 183 switch (err_code) { 184 case 1: 185 break; 186 case 0: 187 err_msg(m_textstr(202, "Unknown terminal \"%s\".\n", "E term"), term_name); 188 return (BAD_TERMINAL); 189 case -1: 190 err_msg(m_textstr(203, "No terminfo database.\n", "E")); 191 return (BAD_TERMINAL); 192 } 193 do { 194 if (S_flag) { 195 build_argv(&argc, &argv); 196 if (argc <= 0) 197 break; 198 } 199 err_code = do_tput(argc, argv); 200 } while (S_flag && err_code == SUCCESS); 201 return (err_code); 202 } 203 204 /*f 205 * Get an input line from stdin and then break it up into an argv array. 206 * If EOF is reached then S_flag is set to 0. Only the first 10 strings 207 * are of any interest. Any extra are ignored. 208 */ 209 STATIC void 210 build_argv(ac, av) 211 int *ac; 212 char ***av; 213 { 214 int i = 0; 215 char *p; 216 static char *v[10+1]; 217 static char buf[LINE_MAX]; 218 if ((*v = fgets(buf, LINE_MAX, stdin)) == NULL) { 219 /* End of file or input error */ 220 S_flag = 0; 221 } else { 222 if ((p = strchr(buf, '\n')) != NULL) 223 *p = '\0'; 224 for (p = buf; i < 10;) { 225 while (isspace(*(unsigned char*) p)) 226 ++p; 227 if (*p == '\0') 228 break; 229 v[i++] = p; 230 while (!isspace(*(unsigned char*) p) && *p != '\0') 231 ++p; 232 if (*p == '\0') 233 break; 234 *p++ = '\0'; 235 } 236 } 237 v[i] = NULL; 238 *ac = i; 239 *av = v; 240 } 241 242 /*f 243 * 244 */ 245 STATIC int 246 do_tput(_argc, _argv) 247 int _argc; 248 char **_argv; 249 { 250 int i; 251 long q[9]; 252 const char *p; 253 char *end_num; 254 255 if (strcmp(*_argv, "init") == 0) 256 init(); 257 else if (strcmp(*_argv, "reset") == 0) 258 reset(); 259 else if (strcmp(*_argv, "longname") == 0) 260 (void) printf("%s\n", longname()); 261 else if ((i = tigetflag(*_argv)) != -1) 262 return (!i); 263 else if ((i = tigetnum(*_argv)) != -2) 264 (void) printf("%d\n", i); 265 else if ((p = tigetstr(*_argv)) != (char*) -1) { 266 if (p == NULL) 267 return (NOT_DEFINED); 268 for (i = 0; i < 9; ++i) { 269 if (1 < _argc) { 270 --_argc; 271 q[i] = strtol(*++_argv, &end_num, 0); 272 if (*end_num != '\0') { 273 /* The parameter must be a string 274 * so we save the pointer instead. 275 */ 276 q[i] = (long) *_argv; 277 } 278 } else { 279 q[i] = 0L; 280 } 281 } 282 (void) putp(tparm(p, q[0], q[1], q[2], q[3], 283 q[4], q[5], q[6], q[7], q[8] 284 )); 285 fflush(stdout); 286 } else { 287 err_msg(m_textstr(1864, "Unknown terminfo capability \"%s\".\n", "E action"), *_argv); 288 return (NOT_VALID); 289 } 290 return (SUCCESS); 291 } 292 293 /*f 294 * 295 */ 296 STATIC void 297 init() 298 { 299 if (init_prog != NULL) 300 (void) system(init_prog); 301 if (init_1string != NULL) 302 putp(init_1string); 303 if (init_2string != NULL) 304 putp(init_2string); 305 #if 0 /* currently not supported by our terminfo database */ 306 if (clear_margins != NULL) 307 putp(clear_margins); 308 if (set_left_margin != NULL) 309 putp(set_left_margin); 310 if (set_right_margin != NULL) 311 putp(set_right_margin); 312 #endif 313 /* TODO: setting of tabs using clear_all_tabs & set_tab. */ 314 if (init_file != NULL) 315 cat(init_file); 316 if (init_3string != NULL) 317 putp(init_3string); 318 } 319 320 /*f 321 * 322 */ 323 STATIC void 324 reset() 325 { 326 if (reset_1string != NULL) 327 putp(reset_1string); 328 if (reset_2string != NULL) 329 putp(reset_2string); 330 if (reset_file != NULL) 331 cat(reset_file); 332 if (reset_3string != NULL) 333 putp(reset_3string); 334 } 335 336 /*f 337 * usage message for tput 338 */ 339 STATIC int 340 usage() 341 { 342 (void) fprintf(stderr, m_strmsg(usage_msg)); 343 return (USAGE); 344 } 345 346 /*f 347 * display error message 348 */ 349 STATIC void 350 err_msg VARARG1(char*, fmt) 351 { 352 va_list ap; 353 (void) fprintf(stderr, "%s: ", _cmdname); 354 va_start(ap, fmt); 355 (void) vfprintf(stderr, m_strmsg(fmt), ap); 356 va_end(ap); 357 } 358 359 /* 360 * Print a file via putp(). 361 */ 362 STATIC void 363 cat(fn) 364 char *fn; 365 { 366 FILE *fp; 367 char buf[LINE_MAX+1]; 368 if ((fp = fopen(fn, "rb")) == NULL) 369 return; 370 while (fgets(buf, LINE_MAX, fp) != NULL) 371 putp(buf); 372 (void) fclose(fp); 373 } 374