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-1997 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 31 /* 32 * University Copyright- Copyright (c) 1982, 1986, 1988 33 * The Regents of the University of California 34 * All Rights Reserved 35 * 36 * University Acknowledgment- Portions of this document are derived from 37 * software developed by the University of California, Berkeley, and its 38 * contributors. 39 */ 40 41 /* 42 * ******************************************************************** 43 * COPYRIGHT NOTICE * 44 * ******************************************************************** 45 * This software is copyright (C) 1982 by Pavel Curtis * 46 * * 47 * Permission is granted to reproduce and distribute * 48 * this file by any means so long as no fee is charged * 49 * above a nominal handling fee and so long as this * 50 * notice is always included in the copies. * 51 * * 52 * Other rights are reserved except as explicitly granted * 53 * by written permission of the author. * 54 * Pavel Curtis * 55 * Computer Science Dept. * 56 * 405 Upson Hall * 57 * Cornell University * 58 * Ithaca, NY 14853 * 59 * * 60 * Ph- (607) 256-4934 * 61 * * 62 * Pavel.Cornell@Udel-Relay (ARPAnet) * 63 * decvax!cornell!pavel (UUCPnet) * 64 * ******************************************************************** 65 */ 66 67 /* 68 * read_entry.c -- Routine for reading in a compiled terminfo file 69 * 70 * $Log: RCS/read_entry.v $ 71 * Revision 2.1 82/10/25 14:49:55 pavel 72 * Added Copyright Notice 73 * 74 * Revision 2.0 82/10/24 15:18:22 pavel 75 * Beta-one Test Release 76 * 77 * Revision 1.3 82/08/23 22:31:15 pavel 78 * The REAL Alpha-one Release Version 79 * 80 * Revision 1.2 82/08/19 19:11:49 pavel 81 * Alpha Test Release One 82 * 83 * Revision 1.1 82/08/12 22:25:13 pavel 84 * Initial revision 85 * 86 * 87 */ 88 89 90 #include <sys/types.h> 91 #include <sys/stat.h> 92 #include <sys/types.h> 93 #include <sys/stat.h> 94 95 #include <fcntl.h> 96 #include <stdlib.h> 97 #include <unistd.h> 98 #include "curses_inc.h" 99 #include "object.h" 100 101 #define OFFSET_BUFSIZE 100 102 103 #define swap(x) (((x >> 8) & 0377) + 256 * (x & 0377)) 104 105 #define min(a, b) ((a) > (b) ? (b) : (a)) 106 107 /* 108 * int 109 * read_entry(filename, ptr) 110 * 111 * Read the compiled terminfo entry in the given file into the 112 * structure pointed to by ptr, allocating space for the string 113 * table and placing its address in ptr->str_table. 114 * 115 */ 116 117 static char TermNames[128]; /* Buffer for terminal names for first term */ 118 static char StringTable[2048]; /* String table for first terminal */ 119 static int beencalled = 0; /* read_entry has been called before */ 120 121 extern void err_abort(char *, ...); 122 extern void syserr_abort(char *, ...); 123 extern void warning(char *, ...); 124 125 int must_swap(void); 126 127 int 128 read_entry(char *filename, struct _bool_struct *bptr, struct _num_struct *nptr, 129 struct _str_struct *sptr) 130 { 131 int fd; 132 int numread; 133 int num_strings; 134 int cur_string; 135 int i; 136 struct header header; 137 unsigned char bytebuf[2]; 138 char ch; 139 char *UB; /* booleans */ 140 short *UN; /* numbers */ 141 char **US; /* strings */ 142 char *pst; /* pointer to string table */ 143 int swapping = must_swap(); 144 extern int BoolCount; 145 extern int NumCount; 146 extern int StrCount; 147 extern long lseek(); 148 unsigned char byte[OFFSET_BUFSIZE][2]; 149 short number[OFFSET_BUFSIZE]; 150 151 fd = open(filename, 0); 152 153 if (fd < 0) 154 return (-1); 155 156 read(fd, &header, sizeof (header)); 157 158 if (swapping) { 159 header.magic = swap(header.magic); 160 header.name_size = swap(header.name_size); 161 header.bool_count = swap(header.bool_count); 162 header.num_count = swap(header.num_count); 163 header.str_count = swap(header.str_count); 164 header.str_size = swap(header.str_size); 165 } 166 167 if (header.magic != MAGIC) { 168 close(fd); 169 return (-1); 170 } 171 172 read(fd, TermNames, min(127, header.name_size)); 173 TermNames[127] = '\0'; 174 if (header.name_size > 127) 175 lseek(fd, (long)(header.name_size - 127), 1); 176 177 UB = &(bptr->_auto_left_margin); 178 UN = &(nptr->_columns); 179 US = &(sptr->strs._back_tab); 180 read(fd, UB, min(BoolCount, header.bool_count)); 181 if (header.bool_count > BoolCount) 182 lseek(fd, (long)(header.bool_count - BoolCount), 1); 183 else 184 for (i = header.bool_count; i < BoolCount; i++) 185 UB[i] = 0; 186 187 if ((header.name_size + header.bool_count) % 2 != 0) 188 read(fd, &ch, 1); 189 190 if (!swapping) 191 read(fd, (char *)UN, min(NumCount, header.num_count) * 2); 192 else { 193 for (i = 0; i < min(header.num_count, NumCount); i++) { 194 read(fd, (char *)bytebuf, 2); 195 if (bytebuf[1] == 0377) { 196 if (bytebuf[0] == 0376) /* -2 == cancelled */ 197 UN[i] = -2; 198 else if (bytebuf[0] == 0377) 199 /* -1 == not there */ 200 UN[i] = -1; 201 else 202 UN[i] = bytebuf[0] + 256 * bytebuf[1]; 203 } else 204 UN[i] = bytebuf[0] + 256 * bytebuf[1]; 205 } 206 } 207 208 if (header.num_count > NumCount) 209 lseek(fd, (long)(2 * (header.num_count - NumCount)), 1); 210 else 211 for (i = header.num_count; i < NumCount; i++) 212 UN[i] = -1; 213 214 if (beencalled) { 215 /* beencalled is non-zero only if we've been called */ 216 pst = malloc((unsigned)header.str_size); 217 if (pst == NULL) { 218 close(fd); 219 return (-1); 220 } 221 } else { 222 pst = StringTable; 223 beencalled++; 224 } 225 226 num_strings = min(StrCount, header.str_count); 227 cur_string = 0; 228 229 while (num_strings > 0) { 230 231 if (swapping) { 232 numread = read(fd, byte, 2*min(num_strings, 233 OFFSET_BUFSIZE)); 234 if (numread <= 0) { 235 close(fd); 236 return (-1); 237 } 238 for (i = 0; i < numread / 2; i++) { 239 if (byte[i][0] == 0377 && byte[i][1] == 0377) 240 /* -1 */ 241 US[i + cur_string] = 0; 242 else if (byte[i][0] == 0376 && 243 byte[i][1] == 0377) 244 /* -2 */ 245 US[i + cur_string] = (char *)-1; 246 else 247 US[i + cur_string] = (byte[i][0] + 248 256*byte[i][1]) + pst; 249 } 250 } else { 251 numread = read(fd, number, 2*min(num_strings, 252 OFFSET_BUFSIZE)); 253 if (numread <= 0) { 254 close(fd); 255 return (-1); 256 } 257 for (i = 0; i < numread / 2; i++) { 258 if (number[i] == -1) /* not there */ 259 US[i + cur_string] = 0; 260 else if (number[i] == -2) /* cancelled */ 261 US[i + cur_string] = (char *)-1; 262 else 263 US[i + cur_string] = number[i] + pst; 264 } 265 } 266 267 cur_string += numread / 2; 268 num_strings -= numread / 2; 269 } 270 271 if (header.str_count > StrCount) 272 lseek(fd, (long)(2 * (header.str_count - StrCount)), 1); 273 else for (i = header.str_count; i < StrCount; i++) 274 US[i] = 0; 275 276 numread = read(fd, pst, header.str_size); 277 close(fd); 278 if (numread != header.str_size) 279 return (-1); 280 281 return (0); 282 } 283 284 /* 285 * int 286 * must_swap() 287 * 288 * Test whether this machine will need byte-swapping 289 * 290 */ 291 292 int 293 must_swap() 294 { 295 union { 296 short num; 297 char byte[2]; 298 } test; 299 300 test.num = 1; 301 return (test.byte[1]); 302 } 303