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