1*10d63b7dSRichard Lowe /* 2*10d63b7dSRichard Lowe * CDDL HEADER START 3*10d63b7dSRichard Lowe * 4*10d63b7dSRichard Lowe * The contents of this file are subject to the terms of the 5*10d63b7dSRichard Lowe * Common Development and Distribution License (the "License"). 6*10d63b7dSRichard Lowe * You may not use this file except in compliance with the License. 7*10d63b7dSRichard Lowe * 8*10d63b7dSRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*10d63b7dSRichard Lowe * or http://www.opensolaris.org/os/licensing. 10*10d63b7dSRichard Lowe * See the License for the specific language governing permissions 11*10d63b7dSRichard Lowe * and limitations under the License. 12*10d63b7dSRichard Lowe * 13*10d63b7dSRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each 14*10d63b7dSRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*10d63b7dSRichard Lowe * If applicable, add the following below this CDDL HEADER, with the 16*10d63b7dSRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying 17*10d63b7dSRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner] 18*10d63b7dSRichard Lowe * 19*10d63b7dSRichard Lowe * CDDL HEADER END 20*10d63b7dSRichard Lowe */ 21*10d63b7dSRichard Lowe /* 22*10d63b7dSRichard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 23*10d63b7dSRichard Lowe * Use is subject to license terms. 24*10d63b7dSRichard Lowe */ 25*10d63b7dSRichard Lowe 26*10d63b7dSRichard Lowe 27*10d63b7dSRichard Lowe /* 28*10d63b7dSRichard Lowe * misc.cc 29*10d63b7dSRichard Lowe * 30*10d63b7dSRichard Lowe * This file contains various unclassified routines. Some main groups: 31*10d63b7dSRichard Lowe * getname 32*10d63b7dSRichard Lowe * Memory allocation 33*10d63b7dSRichard Lowe * String handling 34*10d63b7dSRichard Lowe * Property handling 35*10d63b7dSRichard Lowe * Error message handling 36*10d63b7dSRichard Lowe * Make internal state dumping 37*10d63b7dSRichard Lowe * main routine support 38*10d63b7dSRichard Lowe */ 39*10d63b7dSRichard Lowe 40*10d63b7dSRichard Lowe /* 41*10d63b7dSRichard Lowe * Included files 42*10d63b7dSRichard Lowe */ 43*10d63b7dSRichard Lowe #include <bsd/bsd.h> /* bsd_signal() */ 44*10d63b7dSRichard Lowe #include <mksh/i18n.h> /* get_char_semantics_value() */ 45*10d63b7dSRichard Lowe #include <mksh/misc.h> 46*10d63b7dSRichard Lowe #include <stdarg.h> /* va_list, va_start(), va_end() */ 47*10d63b7dSRichard Lowe #include <stdlib.h> /* mbstowcs() */ 48*10d63b7dSRichard Lowe #include <sys/signal.h> /* SIG_DFL */ 49*10d63b7dSRichard Lowe #include <sys/wait.h> /* wait() */ 50*10d63b7dSRichard Lowe 51*10d63b7dSRichard Lowe #include <string.h> /* strerror() */ 52*10d63b7dSRichard Lowe #include <libintl.h> 53*10d63b7dSRichard Lowe 54*10d63b7dSRichard Lowe 55*10d63b7dSRichard Lowe /* 56*10d63b7dSRichard Lowe * Defined macros 57*10d63b7dSRichard Lowe */ 58*10d63b7dSRichard Lowe 59*10d63b7dSRichard Lowe /* 60*10d63b7dSRichard Lowe * typedefs & structs 61*10d63b7dSRichard Lowe */ 62*10d63b7dSRichard Lowe 63*10d63b7dSRichard Lowe /* 64*10d63b7dSRichard Lowe * Static variables 65*10d63b7dSRichard Lowe */ 66*10d63b7dSRichard Lowe extern "C" { 67*10d63b7dSRichard Lowe void (*sigivalue)(int) = SIG_DFL; 68*10d63b7dSRichard Lowe void (*sigqvalue)(int) = SIG_DFL; 69*10d63b7dSRichard Lowe void (*sigtvalue)(int) = SIG_DFL; 70*10d63b7dSRichard Lowe void (*sighvalue)(int) = SIG_DFL; 71*10d63b7dSRichard Lowe } 72*10d63b7dSRichard Lowe 73*10d63b7dSRichard Lowe long getname_bytes_count = 0; 74*10d63b7dSRichard Lowe long getname_names_count = 0; 75*10d63b7dSRichard Lowe long getname_struct_count = 0; 76*10d63b7dSRichard Lowe 77*10d63b7dSRichard Lowe long freename_bytes_count = 0; 78*10d63b7dSRichard Lowe long freename_names_count = 0; 79*10d63b7dSRichard Lowe long freename_struct_count = 0; 80*10d63b7dSRichard Lowe 81*10d63b7dSRichard Lowe long expandstring_count = 0; 82*10d63b7dSRichard Lowe long getwstring_count = 0; 83*10d63b7dSRichard Lowe 84*10d63b7dSRichard Lowe /* 85*10d63b7dSRichard Lowe * File table of contents 86*10d63b7dSRichard Lowe */ 87*10d63b7dSRichard Lowe static void expand_string(register String string, register int length); 88*10d63b7dSRichard Lowe 89*10d63b7dSRichard Lowe #define FATAL_ERROR_MSG_SIZE 200 90*10d63b7dSRichard Lowe 91*10d63b7dSRichard Lowe /* 92*10d63b7dSRichard Lowe * getmem(size) 93*10d63b7dSRichard Lowe * 94*10d63b7dSRichard Lowe * malloc() version that checks the returned value. 95*10d63b7dSRichard Lowe * 96*10d63b7dSRichard Lowe * Return value: 97*10d63b7dSRichard Lowe * The memory chunk we allocated 98*10d63b7dSRichard Lowe * 99*10d63b7dSRichard Lowe * Parameters: 100*10d63b7dSRichard Lowe * size The size of the chunk we need 101*10d63b7dSRichard Lowe * 102*10d63b7dSRichard Lowe * Global variables used: 103*10d63b7dSRichard Lowe */ 104*10d63b7dSRichard Lowe char * 105*10d63b7dSRichard Lowe getmem(register int size) 106*10d63b7dSRichard Lowe { 107*10d63b7dSRichard Lowe register char *result = (char *) malloc((unsigned) size); 108*10d63b7dSRichard Lowe if (result == NULL) { 109*10d63b7dSRichard Lowe char buf[FATAL_ERROR_MSG_SIZE]; 110*10d63b7dSRichard Lowe sprintf(buf, "*** Error: malloc(%d) failed: %s\n", size, strerror(errno)); 111*10d63b7dSRichard Lowe strcat(buf, gettext("mksh: Fatal error: Out of memory\n")); 112*10d63b7dSRichard Lowe fputs(buf, stderr); 113*10d63b7dSRichard Lowe exit_status = 1; 114*10d63b7dSRichard Lowe exit(1); 115*10d63b7dSRichard Lowe } 116*10d63b7dSRichard Lowe return result; 117*10d63b7dSRichard Lowe } 118*10d63b7dSRichard Lowe 119*10d63b7dSRichard Lowe /* 120*10d63b7dSRichard Lowe * retmem(p) 121*10d63b7dSRichard Lowe * 122*10d63b7dSRichard Lowe * Cover funtion for free() to make it possible to insert advises. 123*10d63b7dSRichard Lowe * 124*10d63b7dSRichard Lowe * Parameters: 125*10d63b7dSRichard Lowe * p The memory block to free 126*10d63b7dSRichard Lowe * 127*10d63b7dSRichard Lowe * Global variables used: 128*10d63b7dSRichard Lowe */ 129*10d63b7dSRichard Lowe void 130*10d63b7dSRichard Lowe retmem(wchar_t *p) 131*10d63b7dSRichard Lowe { 132*10d63b7dSRichard Lowe (void) free((char *) p); 133*10d63b7dSRichard Lowe } 134*10d63b7dSRichard Lowe 135*10d63b7dSRichard Lowe void 136*10d63b7dSRichard Lowe retmem_mb(caddr_t p) 137*10d63b7dSRichard Lowe { 138*10d63b7dSRichard Lowe (void) free(p); 139*10d63b7dSRichard Lowe } 140*10d63b7dSRichard Lowe 141*10d63b7dSRichard Lowe /* 142*10d63b7dSRichard Lowe * getname_fn(name, len, dont_enter) 143*10d63b7dSRichard Lowe * 144*10d63b7dSRichard Lowe * Hash a name string to the corresponding nameblock. 145*10d63b7dSRichard Lowe * 146*10d63b7dSRichard Lowe * Return value: 147*10d63b7dSRichard Lowe * The Name block for the string 148*10d63b7dSRichard Lowe * 149*10d63b7dSRichard Lowe * Parameters: 150*10d63b7dSRichard Lowe * name The string we want to internalize 151*10d63b7dSRichard Lowe * len The length of that string 152*10d63b7dSRichard Lowe * dont_enter Don't enter the name if it does not exist 153*10d63b7dSRichard Lowe * 154*10d63b7dSRichard Lowe * Global variables used: 155*10d63b7dSRichard Lowe * funny The vector of semantic tags for characters 156*10d63b7dSRichard Lowe * hashtab The hashtable used for the nametable 157*10d63b7dSRichard Lowe */ 158*10d63b7dSRichard Lowe Name 159*10d63b7dSRichard Lowe getname_fn(wchar_t *name, register int len, register Boolean dont_enter, register Boolean * foundp) 160*10d63b7dSRichard Lowe { 161*10d63b7dSRichard Lowe register int length; 162*10d63b7dSRichard Lowe register wchar_t *cap = name; 163*10d63b7dSRichard Lowe register Name np; 164*10d63b7dSRichard Lowe static Name_rec empty_Name; 165*10d63b7dSRichard Lowe char *tmp_mbs_buffer = NULL; 166*10d63b7dSRichard Lowe char *mbs_name = mbs_buffer; 167*10d63b7dSRichard Lowe 168*10d63b7dSRichard Lowe /* 169*10d63b7dSRichard Lowe * First figure out how long the string is. 170*10d63b7dSRichard Lowe * If the len argument is -1 we count the chars here. 171*10d63b7dSRichard Lowe */ 172*10d63b7dSRichard Lowe if (len == FIND_LENGTH) { 173*10d63b7dSRichard Lowe length = wcslen(name); 174*10d63b7dSRichard Lowe } else { 175*10d63b7dSRichard Lowe length = len; 176*10d63b7dSRichard Lowe } 177*10d63b7dSRichard Lowe 178*10d63b7dSRichard Lowe Wstring ws; 179*10d63b7dSRichard Lowe ws.init(name, length); 180*10d63b7dSRichard Lowe if (length >= MAXPATHLEN) { 181*10d63b7dSRichard Lowe mbs_name = tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1); 182*10d63b7dSRichard Lowe } 183*10d63b7dSRichard Lowe (void) wcstombs(mbs_name, ws.get_string(), (length * MB_LEN_MAX) + 1); 184*10d63b7dSRichard Lowe 185*10d63b7dSRichard Lowe /* Look for the string */ 186*10d63b7dSRichard Lowe if (dont_enter || (foundp != 0)) { 187*10d63b7dSRichard Lowe np = hashtab.lookup(mbs_name); 188*10d63b7dSRichard Lowe if (foundp != 0) { 189*10d63b7dSRichard Lowe *foundp = (np != 0) ? true : false; 190*10d63b7dSRichard Lowe } 191*10d63b7dSRichard Lowe if ((np != 0) || dont_enter) { 192*10d63b7dSRichard Lowe if(tmp_mbs_buffer != NULL) { 193*10d63b7dSRichard Lowe retmem_mb(tmp_mbs_buffer); 194*10d63b7dSRichard Lowe } 195*10d63b7dSRichard Lowe return np; 196*10d63b7dSRichard Lowe } else { 197*10d63b7dSRichard Lowe np = ALLOC(Name); 198*10d63b7dSRichard Lowe } 199*10d63b7dSRichard Lowe } else { 200*10d63b7dSRichard Lowe Boolean found; 201*10d63b7dSRichard Lowe np = hashtab.insert(mbs_name, found); 202*10d63b7dSRichard Lowe if (found) { 203*10d63b7dSRichard Lowe if(tmp_mbs_buffer != NULL) { 204*10d63b7dSRichard Lowe retmem_mb(tmp_mbs_buffer); 205*10d63b7dSRichard Lowe } 206*10d63b7dSRichard Lowe return np; 207*10d63b7dSRichard Lowe } 208*10d63b7dSRichard Lowe } 209*10d63b7dSRichard Lowe getname_struct_count += sizeof(struct _Name); 210*10d63b7dSRichard Lowe *np = empty_Name; 211*10d63b7dSRichard Lowe 212*10d63b7dSRichard Lowe np->string_mb = strdup(mbs_name); 213*10d63b7dSRichard Lowe if(tmp_mbs_buffer != NULL) { 214*10d63b7dSRichard Lowe retmem_mb(tmp_mbs_buffer); 215*10d63b7dSRichard Lowe mbs_name = tmp_mbs_buffer = NULL; 216*10d63b7dSRichard Lowe } 217*10d63b7dSRichard Lowe getname_bytes_count += strlen(np->string_mb) + 1; 218*10d63b7dSRichard Lowe /* Fill in the new Name */ 219*10d63b7dSRichard Lowe np->stat.time = file_no_time; 220*10d63b7dSRichard Lowe np->hash.length = length; 221*10d63b7dSRichard Lowe /* Scan the namestring to classify it */ 222*10d63b7dSRichard Lowe for (cap = name, len = 0; --length >= 0;) { 223*10d63b7dSRichard Lowe len |= get_char_semantics_value(*cap++); 224*10d63b7dSRichard Lowe } 225*10d63b7dSRichard Lowe np->dollar = BOOLEAN((len & (int) dollar_sem) != 0); 226*10d63b7dSRichard Lowe np->meta = BOOLEAN((len & (int) meta_sem) != 0); 227*10d63b7dSRichard Lowe np->percent = BOOLEAN((len & (int) percent_sem) != 0); 228*10d63b7dSRichard Lowe np->wildcard = BOOLEAN((len & (int) wildcard_sem) != 0); 229*10d63b7dSRichard Lowe np->colon = BOOLEAN((len & (int) colon_sem) != 0); 230*10d63b7dSRichard Lowe np->parenleft = BOOLEAN((len & (int) parenleft_sem) != 0); 231*10d63b7dSRichard Lowe getname_names_count++; 232*10d63b7dSRichard Lowe return np; 233*10d63b7dSRichard Lowe } 234*10d63b7dSRichard Lowe 235*10d63b7dSRichard Lowe void 236*10d63b7dSRichard Lowe store_name(Name name) 237*10d63b7dSRichard Lowe { 238*10d63b7dSRichard Lowe hashtab.insert(name); 239*10d63b7dSRichard Lowe } 240*10d63b7dSRichard Lowe 241*10d63b7dSRichard Lowe void 242*10d63b7dSRichard Lowe free_name(Name name) 243*10d63b7dSRichard Lowe { 244*10d63b7dSRichard Lowe freename_names_count++; 245*10d63b7dSRichard Lowe freename_struct_count += sizeof(struct _Name); 246*10d63b7dSRichard Lowe freename_bytes_count += strlen(name->string_mb) + 1; 247*10d63b7dSRichard Lowe retmem_mb(name->string_mb); 248*10d63b7dSRichard Lowe for (Property next, p = name->prop; p != NULL; p = next) { 249*10d63b7dSRichard Lowe next = p->next; 250*10d63b7dSRichard Lowe free(p); 251*10d63b7dSRichard Lowe } 252*10d63b7dSRichard Lowe free(name); 253*10d63b7dSRichard Lowe } 254*10d63b7dSRichard Lowe 255*10d63b7dSRichard Lowe /* 256*10d63b7dSRichard Lowe * enable_interrupt(handler) 257*10d63b7dSRichard Lowe * 258*10d63b7dSRichard Lowe * This routine sets a new interrupt handler for the signals make 259*10d63b7dSRichard Lowe * wants to deal with. 260*10d63b7dSRichard Lowe * 261*10d63b7dSRichard Lowe * Parameters: 262*10d63b7dSRichard Lowe * handler The function installed as interrupt handler 263*10d63b7dSRichard Lowe * 264*10d63b7dSRichard Lowe * Static variables used: 265*10d63b7dSRichard Lowe * sigivalue The original signal handler 266*10d63b7dSRichard Lowe * sigqvalue The original signal handler 267*10d63b7dSRichard Lowe * sigtvalue The original signal handler 268*10d63b7dSRichard Lowe * sighvalue The original signal handler 269*10d63b7dSRichard Lowe */ 270*10d63b7dSRichard Lowe void 271*10d63b7dSRichard Lowe enable_interrupt(register void (*handler) (int)) 272*10d63b7dSRichard Lowe { 273*10d63b7dSRichard Lowe if (sigivalue != SIG_IGN) { 274*10d63b7dSRichard Lowe (void) bsd_signal(SIGINT, (SIG_PF) handler); 275*10d63b7dSRichard Lowe } 276*10d63b7dSRichard Lowe if (sigqvalue != SIG_IGN) { 277*10d63b7dSRichard Lowe (void) bsd_signal(SIGQUIT, (SIG_PF) handler); 278*10d63b7dSRichard Lowe } 279*10d63b7dSRichard Lowe if (sigtvalue != SIG_IGN) { 280*10d63b7dSRichard Lowe (void) bsd_signal(SIGTERM, (SIG_PF) handler); 281*10d63b7dSRichard Lowe } 282*10d63b7dSRichard Lowe if (sighvalue != SIG_IGN) { 283*10d63b7dSRichard Lowe (void) bsd_signal(SIGHUP, (SIG_PF) handler); 284*10d63b7dSRichard Lowe } 285*10d63b7dSRichard Lowe } 286*10d63b7dSRichard Lowe 287*10d63b7dSRichard Lowe /* 288*10d63b7dSRichard Lowe * setup_char_semantics() 289*10d63b7dSRichard Lowe * 290*10d63b7dSRichard Lowe * Load the vector char_semantics[] with lexical markers 291*10d63b7dSRichard Lowe * 292*10d63b7dSRichard Lowe * Parameters: 293*10d63b7dSRichard Lowe * 294*10d63b7dSRichard Lowe * Global variables used: 295*10d63b7dSRichard Lowe * char_semantics The vector of character semantics that we set 296*10d63b7dSRichard Lowe */ 297*10d63b7dSRichard Lowe void 298*10d63b7dSRichard Lowe setup_char_semantics(void) 299*10d63b7dSRichard Lowe { 300*10d63b7dSRichard Lowe const char *s; 301*10d63b7dSRichard Lowe wchar_t wc_buffer[1]; 302*10d63b7dSRichard Lowe int entry; 303*10d63b7dSRichard Lowe 304*10d63b7dSRichard Lowe if (svr4) { 305*10d63b7dSRichard Lowe s = "@-"; 306*10d63b7dSRichard Lowe } else { 307*10d63b7dSRichard Lowe s = "=@-?!+"; 308*10d63b7dSRichard Lowe } 309*10d63b7dSRichard Lowe for (s; MBTOWC(wc_buffer, s); s++) { 310*10d63b7dSRichard Lowe entry = get_char_semantics_entry(*wc_buffer); 311*10d63b7dSRichard Lowe char_semantics[entry] |= (int) command_prefix_sem; 312*10d63b7dSRichard Lowe } 313*10d63b7dSRichard Lowe char_semantics[dollar_char_entry] |= (int) dollar_sem; 314*10d63b7dSRichard Lowe for (s = "#|=^();&<>*?[]:$`'\"\\\n"; MBTOWC(wc_buffer, s); s++) { 315*10d63b7dSRichard Lowe entry = get_char_semantics_entry(*wc_buffer); 316*10d63b7dSRichard Lowe char_semantics[entry] |= (int) meta_sem; 317*10d63b7dSRichard Lowe } 318*10d63b7dSRichard Lowe char_semantics[percent_char_entry] |= (int) percent_sem; 319*10d63b7dSRichard Lowe for (s = "@*<%?^"; MBTOWC(wc_buffer, s); s++) { 320*10d63b7dSRichard Lowe entry = get_char_semantics_entry(*wc_buffer); 321*10d63b7dSRichard Lowe char_semantics[entry] |= (int) special_macro_sem; 322*10d63b7dSRichard Lowe } 323*10d63b7dSRichard Lowe for (s = "?[*"; MBTOWC(wc_buffer, s); s++) { 324*10d63b7dSRichard Lowe entry = get_char_semantics_entry(*wc_buffer); 325*10d63b7dSRichard Lowe char_semantics[entry] |= (int) wildcard_sem; 326*10d63b7dSRichard Lowe } 327*10d63b7dSRichard Lowe char_semantics[colon_char_entry] |= (int) colon_sem; 328*10d63b7dSRichard Lowe char_semantics[parenleft_char_entry] |= (int) parenleft_sem; 329*10d63b7dSRichard Lowe } 330*10d63b7dSRichard Lowe 331*10d63b7dSRichard Lowe /* 332*10d63b7dSRichard Lowe * errmsg(errnum) 333*10d63b7dSRichard Lowe * 334*10d63b7dSRichard Lowe * Return the error message for a system call error 335*10d63b7dSRichard Lowe * 336*10d63b7dSRichard Lowe * Return value: 337*10d63b7dSRichard Lowe * An error message string 338*10d63b7dSRichard Lowe * 339*10d63b7dSRichard Lowe * Parameters: 340*10d63b7dSRichard Lowe * errnum The number of the error we want to describe 341*10d63b7dSRichard Lowe * 342*10d63b7dSRichard Lowe * Global variables used: 343*10d63b7dSRichard Lowe * sys_errlist A vector of error messages 344*10d63b7dSRichard Lowe * sys_nerr The size of sys_errlist 345*10d63b7dSRichard Lowe */ 346*10d63b7dSRichard Lowe char * 347*10d63b7dSRichard Lowe errmsg(int errnum) 348*10d63b7dSRichard Lowe { 349*10d63b7dSRichard Lowe 350*10d63b7dSRichard Lowe extern int sys_nerr; 351*10d63b7dSRichard Lowe char *errbuf; 352*10d63b7dSRichard Lowe 353*10d63b7dSRichard Lowe if ((errnum < 0) || (errnum > sys_nerr)) { 354*10d63b7dSRichard Lowe errbuf = getmem(6+1+11+1); 355*10d63b7dSRichard Lowe (void) sprintf(errbuf, gettext("Error %d"), errnum); 356*10d63b7dSRichard Lowe return errbuf; 357*10d63b7dSRichard Lowe } else { 358*10d63b7dSRichard Lowe return strerror(errnum); 359*10d63b7dSRichard Lowe 360*10d63b7dSRichard Lowe } 361*10d63b7dSRichard Lowe } 362*10d63b7dSRichard Lowe 363*10d63b7dSRichard Lowe static char static_buf[MAXPATHLEN*3]; 364*10d63b7dSRichard Lowe 365*10d63b7dSRichard Lowe /* 366*10d63b7dSRichard Lowe * fatal_mksh(format, args...) 367*10d63b7dSRichard Lowe * 368*10d63b7dSRichard Lowe * Print a message and die 369*10d63b7dSRichard Lowe * 370*10d63b7dSRichard Lowe * Parameters: 371*10d63b7dSRichard Lowe * format printf type format string 372*10d63b7dSRichard Lowe * args Arguments to match the format 373*10d63b7dSRichard Lowe */ 374*10d63b7dSRichard Lowe /*VARARGS*/ 375*10d63b7dSRichard Lowe void 376*10d63b7dSRichard Lowe fatal_mksh(const char *message, ...) 377*10d63b7dSRichard Lowe { 378*10d63b7dSRichard Lowe va_list args; 379*10d63b7dSRichard Lowe char *buf = static_buf; 380*10d63b7dSRichard Lowe char *mksh_fat_err = gettext("mksh: Fatal error: "); 381*10d63b7dSRichard Lowe char *cur_wrk_dir = gettext("Current working directory: "); 382*10d63b7dSRichard Lowe int mksh_fat_err_len = strlen(mksh_fat_err); 383*10d63b7dSRichard Lowe 384*10d63b7dSRichard Lowe va_start(args, message); 385*10d63b7dSRichard Lowe (void) fflush(stdout); 386*10d63b7dSRichard Lowe (void) strcpy(buf, mksh_fat_err); 387*10d63b7dSRichard Lowe size_t buf_len = vsnprintf(static_buf + mksh_fat_err_len, 388*10d63b7dSRichard Lowe sizeof(static_buf) - mksh_fat_err_len, 389*10d63b7dSRichard Lowe message, args) 390*10d63b7dSRichard Lowe + mksh_fat_err_len 391*10d63b7dSRichard Lowe + strlen(cur_wrk_dir) 392*10d63b7dSRichard Lowe + strlen(get_current_path_mksh()) 393*10d63b7dSRichard Lowe + 3; // "\n\n" 394*10d63b7dSRichard Lowe va_end(args); 395*10d63b7dSRichard Lowe if (buf_len >= sizeof(static_buf)) { 396*10d63b7dSRichard Lowe buf = getmem(buf_len); 397*10d63b7dSRichard Lowe (void) strcpy(buf, mksh_fat_err); 398*10d63b7dSRichard Lowe va_start(args, message); 399*10d63b7dSRichard Lowe (void) vsprintf(buf + mksh_fat_err_len, message, args); 400*10d63b7dSRichard Lowe va_end(args); 401*10d63b7dSRichard Lowe } 402*10d63b7dSRichard Lowe (void) strcat(buf, "\n"); 403*10d63b7dSRichard Lowe /* 404*10d63b7dSRichard Lowe if (report_pwd) { 405*10d63b7dSRichard Lowe */ 406*10d63b7dSRichard Lowe if (1) { 407*10d63b7dSRichard Lowe (void) strcat(buf, cur_wrk_dir); 408*10d63b7dSRichard Lowe (void) strcat(buf, get_current_path_mksh()); 409*10d63b7dSRichard Lowe (void) strcat(buf, "\n"); 410*10d63b7dSRichard Lowe } 411*10d63b7dSRichard Lowe (void) fputs(buf, stderr); 412*10d63b7dSRichard Lowe (void) fflush(stderr); 413*10d63b7dSRichard Lowe if (buf != static_buf) { 414*10d63b7dSRichard Lowe retmem_mb(buf); 415*10d63b7dSRichard Lowe } 416*10d63b7dSRichard Lowe exit_status = 1; 417*10d63b7dSRichard Lowe exit(1); 418*10d63b7dSRichard Lowe } 419*10d63b7dSRichard Lowe 420*10d63b7dSRichard Lowe /* 421*10d63b7dSRichard Lowe * fatal_reader_mksh(format, args...) 422*10d63b7dSRichard Lowe * 423*10d63b7dSRichard Lowe * Parameters: 424*10d63b7dSRichard Lowe * format printf style format string 425*10d63b7dSRichard Lowe * args arguments to match the format 426*10d63b7dSRichard Lowe */ 427*10d63b7dSRichard Lowe /*VARARGS*/ 428*10d63b7dSRichard Lowe void 429*10d63b7dSRichard Lowe fatal_reader_mksh(const char * pattern, ...) 430*10d63b7dSRichard Lowe { 431*10d63b7dSRichard Lowe va_list args; 432*10d63b7dSRichard Lowe char message[1000]; 433*10d63b7dSRichard Lowe 434*10d63b7dSRichard Lowe va_start(args, pattern); 435*10d63b7dSRichard Lowe /* 436*10d63b7dSRichard Lowe if (file_being_read != NULL) { 437*10d63b7dSRichard Lowe WCSTOMBS(mbs_buffer, file_being_read); 438*10d63b7dSRichard Lowe if (line_number != 0) { 439*10d63b7dSRichard Lowe (void) sprintf(message, 440*10d63b7dSRichard Lowe gettext("%s, line %d: %s"), 441*10d63b7dSRichard Lowe mbs_buffer, 442*10d63b7dSRichard Lowe line_number, 443*10d63b7dSRichard Lowe pattern); 444*10d63b7dSRichard Lowe } else { 445*10d63b7dSRichard Lowe (void) sprintf(message, 446*10d63b7dSRichard Lowe "%s: %s", 447*10d63b7dSRichard Lowe mbs_buffer, 448*10d63b7dSRichard Lowe pattern); 449*10d63b7dSRichard Lowe } 450*10d63b7dSRichard Lowe pattern = message; 451*10d63b7dSRichard Lowe } 452*10d63b7dSRichard Lowe */ 453*10d63b7dSRichard Lowe 454*10d63b7dSRichard Lowe (void) fflush(stdout); 455*10d63b7dSRichard Lowe (void) fprintf(stderr, gettext("mksh: Fatal error in reader: ")); 456*10d63b7dSRichard Lowe (void) vfprintf(stderr, pattern, args); 457*10d63b7dSRichard Lowe (void) fprintf(stderr, "\n"); 458*10d63b7dSRichard Lowe va_end(args); 459*10d63b7dSRichard Lowe 460*10d63b7dSRichard Lowe /* 461*10d63b7dSRichard Lowe if (temp_file_name != NULL) { 462*10d63b7dSRichard Lowe (void) fprintf(stderr, 463*10d63b7dSRichard Lowe gettext("mksh: Temp-file %s not removed\n"), 464*10d63b7dSRichard Lowe temp_file_name->string_mb); 465*10d63b7dSRichard Lowe temp_file_name = NULL; 466*10d63b7dSRichard Lowe } 467*10d63b7dSRichard Lowe */ 468*10d63b7dSRichard Lowe 469*10d63b7dSRichard Lowe /* 470*10d63b7dSRichard Lowe if (report_pwd) { 471*10d63b7dSRichard Lowe */ 472*10d63b7dSRichard Lowe if (1) { 473*10d63b7dSRichard Lowe (void) fprintf(stderr, 474*10d63b7dSRichard Lowe gettext("Current working directory %s\n"), 475*10d63b7dSRichard Lowe get_current_path_mksh()); 476*10d63b7dSRichard Lowe } 477*10d63b7dSRichard Lowe (void) fflush(stderr); 478*10d63b7dSRichard Lowe exit_status = 1; 479*10d63b7dSRichard Lowe exit(1); 480*10d63b7dSRichard Lowe } 481*10d63b7dSRichard Lowe 482*10d63b7dSRichard Lowe /* 483*10d63b7dSRichard Lowe * warning_mksh(format, args...) 484*10d63b7dSRichard Lowe * 485*10d63b7dSRichard Lowe * Print a message and continue. 486*10d63b7dSRichard Lowe * 487*10d63b7dSRichard Lowe * Parameters: 488*10d63b7dSRichard Lowe * format printf type format string 489*10d63b7dSRichard Lowe * args Arguments to match the format 490*10d63b7dSRichard Lowe */ 491*10d63b7dSRichard Lowe /*VARARGS*/ 492*10d63b7dSRichard Lowe void 493*10d63b7dSRichard Lowe warning_mksh(char * message, ...) 494*10d63b7dSRichard Lowe { 495*10d63b7dSRichard Lowe va_list args; 496*10d63b7dSRichard Lowe 497*10d63b7dSRichard Lowe va_start(args, message); 498*10d63b7dSRichard Lowe (void) fflush(stdout); 499*10d63b7dSRichard Lowe (void) fprintf(stderr, gettext("mksh: Warning: ")); 500*10d63b7dSRichard Lowe (void) vfprintf(stderr, message, args); 501*10d63b7dSRichard Lowe (void) fprintf(stderr, "\n"); 502*10d63b7dSRichard Lowe va_end(args); 503*10d63b7dSRichard Lowe /* 504*10d63b7dSRichard Lowe if (report_pwd) { 505*10d63b7dSRichard Lowe */ 506*10d63b7dSRichard Lowe if (1) { 507*10d63b7dSRichard Lowe (void) fprintf(stderr, 508*10d63b7dSRichard Lowe gettext("Current working directory %s\n"), 509*10d63b7dSRichard Lowe get_current_path_mksh()); 510*10d63b7dSRichard Lowe } 511*10d63b7dSRichard Lowe (void) fflush(stderr); 512*10d63b7dSRichard Lowe } 513*10d63b7dSRichard Lowe 514*10d63b7dSRichard Lowe /* 515*10d63b7dSRichard Lowe * get_current_path_mksh() 516*10d63b7dSRichard Lowe * 517*10d63b7dSRichard Lowe * Stuff current_path with the current path if it isnt there already. 518*10d63b7dSRichard Lowe * 519*10d63b7dSRichard Lowe * Parameters: 520*10d63b7dSRichard Lowe * 521*10d63b7dSRichard Lowe * Global variables used: 522*10d63b7dSRichard Lowe */ 523*10d63b7dSRichard Lowe char * 524*10d63b7dSRichard Lowe get_current_path_mksh(void) 525*10d63b7dSRichard Lowe { 526*10d63b7dSRichard Lowe char pwd[(MAXPATHLEN * MB_LEN_MAX)]; 527*10d63b7dSRichard Lowe static char *current_path; 528*10d63b7dSRichard Lowe 529*10d63b7dSRichard Lowe if (current_path == NULL) { 530*10d63b7dSRichard Lowe getcwd(pwd, sizeof(pwd)); 531*10d63b7dSRichard Lowe if (pwd[0] == (int) nul_char) { 532*10d63b7dSRichard Lowe pwd[0] = (int) slash_char; 533*10d63b7dSRichard Lowe pwd[1] = (int) nul_char; 534*10d63b7dSRichard Lowe } 535*10d63b7dSRichard Lowe current_path = strdup(pwd); 536*10d63b7dSRichard Lowe } 537*10d63b7dSRichard Lowe return current_path; 538*10d63b7dSRichard Lowe } 539*10d63b7dSRichard Lowe 540*10d63b7dSRichard Lowe /* 541*10d63b7dSRichard Lowe * append_prop(target, type) 542*10d63b7dSRichard Lowe * 543*10d63b7dSRichard Lowe * Create a new property and append it to the property list of a Name. 544*10d63b7dSRichard Lowe * 545*10d63b7dSRichard Lowe * Return value: 546*10d63b7dSRichard Lowe * A new property block for the target 547*10d63b7dSRichard Lowe * 548*10d63b7dSRichard Lowe * Parameters: 549*10d63b7dSRichard Lowe * target The target that wants a new property 550*10d63b7dSRichard Lowe * type The type of property being requested 551*10d63b7dSRichard Lowe * 552*10d63b7dSRichard Lowe * Global variables used: 553*10d63b7dSRichard Lowe */ 554*10d63b7dSRichard Lowe Property 555*10d63b7dSRichard Lowe append_prop(register Name target, register Property_id type) 556*10d63b7dSRichard Lowe { 557*10d63b7dSRichard Lowe register Property *insert = &target->prop; 558*10d63b7dSRichard Lowe register Property prop = *insert; 559*10d63b7dSRichard Lowe register int size; 560*10d63b7dSRichard Lowe 561*10d63b7dSRichard Lowe switch (type) { 562*10d63b7dSRichard Lowe case conditional_prop: 563*10d63b7dSRichard Lowe size = sizeof (struct Conditional); 564*10d63b7dSRichard Lowe break; 565*10d63b7dSRichard Lowe case line_prop: 566*10d63b7dSRichard Lowe size = sizeof (struct Line); 567*10d63b7dSRichard Lowe break; 568*10d63b7dSRichard Lowe case macro_prop: 569*10d63b7dSRichard Lowe size = sizeof (struct _Macro); 570*10d63b7dSRichard Lowe break; 571*10d63b7dSRichard Lowe case makefile_prop: 572*10d63b7dSRichard Lowe size = sizeof (struct Makefile); 573*10d63b7dSRichard Lowe break; 574*10d63b7dSRichard Lowe case member_prop: 575*10d63b7dSRichard Lowe size = sizeof (struct Member); 576*10d63b7dSRichard Lowe break; 577*10d63b7dSRichard Lowe case recursive_prop: 578*10d63b7dSRichard Lowe size = sizeof (struct Recursive); 579*10d63b7dSRichard Lowe break; 580*10d63b7dSRichard Lowe case sccs_prop: 581*10d63b7dSRichard Lowe size = sizeof (struct Sccs); 582*10d63b7dSRichard Lowe break; 583*10d63b7dSRichard Lowe case suffix_prop: 584*10d63b7dSRichard Lowe size = sizeof (struct Suffix); 585*10d63b7dSRichard Lowe break; 586*10d63b7dSRichard Lowe case target_prop: 587*10d63b7dSRichard Lowe size = sizeof (struct Target); 588*10d63b7dSRichard Lowe break; 589*10d63b7dSRichard Lowe case time_prop: 590*10d63b7dSRichard Lowe size = sizeof (struct STime); 591*10d63b7dSRichard Lowe break; 592*10d63b7dSRichard Lowe case vpath_alias_prop: 593*10d63b7dSRichard Lowe size = sizeof (struct Vpath_alias); 594*10d63b7dSRichard Lowe break; 595*10d63b7dSRichard Lowe case long_member_name_prop: 596*10d63b7dSRichard Lowe size = sizeof (struct Long_member_name); 597*10d63b7dSRichard Lowe break; 598*10d63b7dSRichard Lowe case macro_append_prop: 599*10d63b7dSRichard Lowe size = sizeof (struct _Macro_appendix); 600*10d63b7dSRichard Lowe break; 601*10d63b7dSRichard Lowe case env_mem_prop: 602*10d63b7dSRichard Lowe size = sizeof (struct _Env_mem); 603*10d63b7dSRichard Lowe break; 604*10d63b7dSRichard Lowe default: 605*10d63b7dSRichard Lowe fatal_mksh(gettext("Internal error. Unknown prop type %d"), type); 606*10d63b7dSRichard Lowe } 607*10d63b7dSRichard Lowe for (; prop != NULL; insert = &prop->next, prop = *insert); 608*10d63b7dSRichard Lowe size += PROPERTY_HEAD_SIZE; 609*10d63b7dSRichard Lowe *insert = prop = (Property) getmem(size); 610*10d63b7dSRichard Lowe memset((char *) prop, 0, size); 611*10d63b7dSRichard Lowe prop->type = type; 612*10d63b7dSRichard Lowe prop->next = NULL; 613*10d63b7dSRichard Lowe return prop; 614*10d63b7dSRichard Lowe } 615*10d63b7dSRichard Lowe 616*10d63b7dSRichard Lowe /* 617*10d63b7dSRichard Lowe * maybe_append_prop(target, type) 618*10d63b7dSRichard Lowe * 619*10d63b7dSRichard Lowe * Append a property to the Name if none of this type exists 620*10d63b7dSRichard Lowe * else return the one already there 621*10d63b7dSRichard Lowe * 622*10d63b7dSRichard Lowe * Return value: 623*10d63b7dSRichard Lowe * A property of the requested type for the target 624*10d63b7dSRichard Lowe * 625*10d63b7dSRichard Lowe * Parameters: 626*10d63b7dSRichard Lowe * target The target that wants a new property 627*10d63b7dSRichard Lowe * type The type of property being requested 628*10d63b7dSRichard Lowe * 629*10d63b7dSRichard Lowe * Global variables used: 630*10d63b7dSRichard Lowe */ 631*10d63b7dSRichard Lowe Property 632*10d63b7dSRichard Lowe maybe_append_prop(register Name target, register Property_id type) 633*10d63b7dSRichard Lowe { 634*10d63b7dSRichard Lowe register Property prop; 635*10d63b7dSRichard Lowe 636*10d63b7dSRichard Lowe if ((prop = get_prop(target->prop, type)) != NULL) { 637*10d63b7dSRichard Lowe return prop; 638*10d63b7dSRichard Lowe } 639*10d63b7dSRichard Lowe return append_prop(target, type); 640*10d63b7dSRichard Lowe } 641*10d63b7dSRichard Lowe 642*10d63b7dSRichard Lowe /* 643*10d63b7dSRichard Lowe * get_prop(start, type) 644*10d63b7dSRichard Lowe * 645*10d63b7dSRichard Lowe * Scan the property list of a Name to find the next property 646*10d63b7dSRichard Lowe * of a given type. 647*10d63b7dSRichard Lowe * 648*10d63b7dSRichard Lowe * Return value: 649*10d63b7dSRichard Lowe * The first property of the type, if any left 650*10d63b7dSRichard Lowe * 651*10d63b7dSRichard Lowe * Parameters: 652*10d63b7dSRichard Lowe * start The first property block to check for type 653*10d63b7dSRichard Lowe * type The type of property block we need 654*10d63b7dSRichard Lowe * 655*10d63b7dSRichard Lowe * Global variables used: 656*10d63b7dSRichard Lowe */ 657*10d63b7dSRichard Lowe Property 658*10d63b7dSRichard Lowe get_prop(register Property start, register Property_id type) 659*10d63b7dSRichard Lowe { 660*10d63b7dSRichard Lowe for (; start != NULL; start = start->next) { 661*10d63b7dSRichard Lowe if (start->type == type) { 662*10d63b7dSRichard Lowe return start; 663*10d63b7dSRichard Lowe } 664*10d63b7dSRichard Lowe } 665*10d63b7dSRichard Lowe return NULL; 666*10d63b7dSRichard Lowe } 667*10d63b7dSRichard Lowe 668*10d63b7dSRichard Lowe /* 669*10d63b7dSRichard Lowe * append_string(from, to, length) 670*10d63b7dSRichard Lowe * 671*10d63b7dSRichard Lowe * Append a C string to a make string expanding it if nessecary 672*10d63b7dSRichard Lowe * 673*10d63b7dSRichard Lowe * Parameters: 674*10d63b7dSRichard Lowe * from The source (C style) string 675*10d63b7dSRichard Lowe * to The destination (make style) string 676*10d63b7dSRichard Lowe * length The length of the from string 677*10d63b7dSRichard Lowe * 678*10d63b7dSRichard Lowe * Global variables used: 679*10d63b7dSRichard Lowe */ 680*10d63b7dSRichard Lowe void 681*10d63b7dSRichard Lowe append_string(register wchar_t *from, register String to, register int length) 682*10d63b7dSRichard Lowe { 683*10d63b7dSRichard Lowe if (length == FIND_LENGTH) { 684*10d63b7dSRichard Lowe length = wcslen(from); 685*10d63b7dSRichard Lowe } 686*10d63b7dSRichard Lowe if (to->buffer.start == NULL) { 687*10d63b7dSRichard Lowe expand_string(to, 32 + length); 688*10d63b7dSRichard Lowe } 689*10d63b7dSRichard Lowe if (to->buffer.end - to->text.p <= length) { 690*10d63b7dSRichard Lowe expand_string(to, 691*10d63b7dSRichard Lowe (to->buffer.end - to->buffer.start) * 2 + 692*10d63b7dSRichard Lowe length); 693*10d63b7dSRichard Lowe } 694*10d63b7dSRichard Lowe if (length > 0) { 695*10d63b7dSRichard Lowe (void) wcsncpy(to->text.p, from, length); 696*10d63b7dSRichard Lowe to->text.p += length; 697*10d63b7dSRichard Lowe } 698*10d63b7dSRichard Lowe *(to->text.p) = (int) nul_char; 699*10d63b7dSRichard Lowe } 700*10d63b7dSRichard Lowe 701*10d63b7dSRichard Lowe wchar_t * get_wstring(char *from) { 702*10d63b7dSRichard Lowe if(from == NULL) { 703*10d63b7dSRichard Lowe return NULL; 704*10d63b7dSRichard Lowe } 705*10d63b7dSRichard Lowe getwstring_count++; 706*10d63b7dSRichard Lowe wchar_t * wcbuf = ALLOC_WC(strlen(from) + 1); 707*10d63b7dSRichard Lowe mbstowcs(wcbuf, from, strlen(from)+1); 708*10d63b7dSRichard Lowe return wcbuf; 709*10d63b7dSRichard Lowe } 710*10d63b7dSRichard Lowe 711*10d63b7dSRichard Lowe void 712*10d63b7dSRichard Lowe append_string(register char *from, register String to, register int length) 713*10d63b7dSRichard Lowe { 714*10d63b7dSRichard Lowe if (length == FIND_LENGTH) { 715*10d63b7dSRichard Lowe length = strlen(from); 716*10d63b7dSRichard Lowe } 717*10d63b7dSRichard Lowe if (to->buffer.start == NULL) { 718*10d63b7dSRichard Lowe expand_string(to, 32 + length); 719*10d63b7dSRichard Lowe } 720*10d63b7dSRichard Lowe if (to->buffer.end - to->text.p <= length) { 721*10d63b7dSRichard Lowe expand_string(to, 722*10d63b7dSRichard Lowe (to->buffer.end - to->buffer.start) * 2 + 723*10d63b7dSRichard Lowe length); 724*10d63b7dSRichard Lowe } 725*10d63b7dSRichard Lowe if (length > 0) { 726*10d63b7dSRichard Lowe (void) mbstowcs(to->text.p, from, length); 727*10d63b7dSRichard Lowe to->text.p += length; 728*10d63b7dSRichard Lowe } 729*10d63b7dSRichard Lowe *(to->text.p) = (int) nul_char; 730*10d63b7dSRichard Lowe } 731*10d63b7dSRichard Lowe 732*10d63b7dSRichard Lowe /* 733*10d63b7dSRichard Lowe * expand_string(string, length) 734*10d63b7dSRichard Lowe * 735*10d63b7dSRichard Lowe * Allocate more memory for strings that run out of space. 736*10d63b7dSRichard Lowe * 737*10d63b7dSRichard Lowe * Parameters: 738*10d63b7dSRichard Lowe * string The make style string we want to expand 739*10d63b7dSRichard Lowe * length The new length we need 740*10d63b7dSRichard Lowe * 741*10d63b7dSRichard Lowe * Global variables used: 742*10d63b7dSRichard Lowe */ 743*10d63b7dSRichard Lowe static void 744*10d63b7dSRichard Lowe expand_string(register String string, register int length) 745*10d63b7dSRichard Lowe { 746*10d63b7dSRichard Lowe register wchar_t *p; 747*10d63b7dSRichard Lowe 748*10d63b7dSRichard Lowe if (string->buffer.start == NULL) { 749*10d63b7dSRichard Lowe /* For strings that have no memory allocated */ 750*10d63b7dSRichard Lowe string->buffer.start = 751*10d63b7dSRichard Lowe string->text.p = 752*10d63b7dSRichard Lowe string->text.end = 753*10d63b7dSRichard Lowe ALLOC_WC(length); 754*10d63b7dSRichard Lowe string->buffer.end = string->buffer.start + length; 755*10d63b7dSRichard Lowe string->text.p[0] = (int) nul_char; 756*10d63b7dSRichard Lowe string->free_after_use = true; 757*10d63b7dSRichard Lowe expandstring_count++; 758*10d63b7dSRichard Lowe return; 759*10d63b7dSRichard Lowe } 760*10d63b7dSRichard Lowe if (string->buffer.end - string->buffer.start >= length) { 761*10d63b7dSRichard Lowe /* If we really don't need more memory. */ 762*10d63b7dSRichard Lowe return; 763*10d63b7dSRichard Lowe } 764*10d63b7dSRichard Lowe /* 765*10d63b7dSRichard Lowe * Get more memory, copy the string and free the old buffer if 766*10d63b7dSRichard Lowe * it is was malloc()'ed. 767*10d63b7dSRichard Lowe */ 768*10d63b7dSRichard Lowe expandstring_count++; 769*10d63b7dSRichard Lowe p = ALLOC_WC(length); 770*10d63b7dSRichard Lowe (void) wcscpy(p, string->buffer.start); 771*10d63b7dSRichard Lowe string->text.p = p + (string->text.p - string->buffer.start); 772*10d63b7dSRichard Lowe string->text.end = p + (string->text.end - string->buffer.start); 773*10d63b7dSRichard Lowe string->buffer.end = p + length; 774*10d63b7dSRichard Lowe if (string->free_after_use) { 775*10d63b7dSRichard Lowe retmem(string->buffer.start); 776*10d63b7dSRichard Lowe } 777*10d63b7dSRichard Lowe string->buffer.start = p; 778*10d63b7dSRichard Lowe string->free_after_use = true; 779*10d63b7dSRichard Lowe } 780*10d63b7dSRichard Lowe 781*10d63b7dSRichard Lowe /* 782*10d63b7dSRichard Lowe * append_char(from, to) 783*10d63b7dSRichard Lowe * 784*10d63b7dSRichard Lowe * Append one char to a make string expanding it if nessecary 785*10d63b7dSRichard Lowe * 786*10d63b7dSRichard Lowe * Parameters: 787*10d63b7dSRichard Lowe * from Single character to append to string 788*10d63b7dSRichard Lowe * to The destination (make style) string 789*10d63b7dSRichard Lowe * 790*10d63b7dSRichard Lowe * Global variables used: 791*10d63b7dSRichard Lowe */ 792*10d63b7dSRichard Lowe void 793*10d63b7dSRichard Lowe append_char(wchar_t from, register String to) 794*10d63b7dSRichard Lowe { 795*10d63b7dSRichard Lowe if (to->buffer.start == NULL) { 796*10d63b7dSRichard Lowe expand_string(to, 32); 797*10d63b7dSRichard Lowe } 798*10d63b7dSRichard Lowe if (to->buffer.end - to->text.p <= 2) { 799*10d63b7dSRichard Lowe expand_string(to, to->buffer.end - to->buffer.start + 32); 800*10d63b7dSRichard Lowe } 801*10d63b7dSRichard Lowe *(to->text.p)++ = from; 802*10d63b7dSRichard Lowe *(to->text.p) = (int) nul_char; 803*10d63b7dSRichard Lowe } 804*10d63b7dSRichard Lowe 805*10d63b7dSRichard Lowe /* 806*10d63b7dSRichard Lowe * handle_interrupt_mksh() 807*10d63b7dSRichard Lowe * 808*10d63b7dSRichard Lowe * This is where C-C traps are caught. 809*10d63b7dSRichard Lowe */ 810*10d63b7dSRichard Lowe void 811*10d63b7dSRichard Lowe handle_interrupt_mksh(int) 812*10d63b7dSRichard Lowe { 813*10d63b7dSRichard Lowe (void) fflush(stdout); 814*10d63b7dSRichard Lowe /* Make sure the processes running under us terminate first. */ 815*10d63b7dSRichard Lowe if (childPid > 0) { 816*10d63b7dSRichard Lowe kill(childPid, SIGTERM); 817*10d63b7dSRichard Lowe childPid = -1; 818*10d63b7dSRichard Lowe } 819*10d63b7dSRichard Lowe while (wait((int *) NULL) != -1); 820*10d63b7dSRichard Lowe exit_status = 2; 821*10d63b7dSRichard Lowe exit(2); 822*10d63b7dSRichard Lowe } 823*10d63b7dSRichard Lowe 824*10d63b7dSRichard Lowe /* 825*10d63b7dSRichard Lowe * setup_interrupt() 826*10d63b7dSRichard Lowe * 827*10d63b7dSRichard Lowe * This routine saves the original interrupt handler pointers 828*10d63b7dSRichard Lowe * 829*10d63b7dSRichard Lowe * Parameters: 830*10d63b7dSRichard Lowe * 831*10d63b7dSRichard Lowe * Static variables used: 832*10d63b7dSRichard Lowe * sigivalue The original signal handler 833*10d63b7dSRichard Lowe * sigqvalue The original signal handler 834*10d63b7dSRichard Lowe * sigtvalue The original signal handler 835*10d63b7dSRichard Lowe * sighvalue The original signal handler 836*10d63b7dSRichard Lowe */ 837*10d63b7dSRichard Lowe void 838*10d63b7dSRichard Lowe setup_interrupt(register void (*handler) (int)) 839*10d63b7dSRichard Lowe { 840*10d63b7dSRichard Lowe sigivalue = bsd_signal(SIGINT, SIG_IGN); 841*10d63b7dSRichard Lowe sigqvalue = bsd_signal(SIGQUIT, SIG_IGN); 842*10d63b7dSRichard Lowe sigtvalue = bsd_signal(SIGTERM, SIG_IGN); 843*10d63b7dSRichard Lowe sighvalue = bsd_signal(SIGHUP, SIG_IGN); 844*10d63b7dSRichard Lowe enable_interrupt(handler); 845*10d63b7dSRichard Lowe } 846*10d63b7dSRichard Lowe 847*10d63b7dSRichard Lowe 848*10d63b7dSRichard Lowe void 849*10d63b7dSRichard Lowe mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n) 850*10d63b7dSRichard Lowe { 851*10d63b7dSRichard Lowe if(mbstowcs(pwcs, s, n) == -1) { 852*10d63b7dSRichard Lowe fatal_mksh(gettext("The string `%s' is not valid in current locale"), s); 853*10d63b7dSRichard Lowe } 854*10d63b7dSRichard Lowe } 855*10d63b7dSRichard Lowe 856*10d63b7dSRichard Lowe 857*10d63b7dSRichard Lowe 858*10d63b7dSRichard Lowe Wstring::Wstring() 859*10d63b7dSRichard Lowe { 860*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf); 861*10d63b7dSRichard Lowe } 862*10d63b7dSRichard Lowe 863*10d63b7dSRichard Lowe Wstring::Wstring(struct _Name * name) 864*10d63b7dSRichard Lowe { 865*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf); 866*10d63b7dSRichard Lowe append_string(name->string_mb, &string, name->hash.length); 867*10d63b7dSRichard Lowe } 868*10d63b7dSRichard Lowe 869*10d63b7dSRichard Lowe Wstring::~Wstring() 870*10d63b7dSRichard Lowe { 871*10d63b7dSRichard Lowe if(string.free_after_use) { 872*10d63b7dSRichard Lowe retmem(string.buffer.start); 873*10d63b7dSRichard Lowe } 874*10d63b7dSRichard Lowe } 875*10d63b7dSRichard Lowe 876*10d63b7dSRichard Lowe void 877*10d63b7dSRichard Lowe Wstring::init(struct _Name * name) 878*10d63b7dSRichard Lowe { 879*10d63b7dSRichard Lowe if(string.free_after_use) { 880*10d63b7dSRichard Lowe retmem(string.buffer.start); 881*10d63b7dSRichard Lowe } 882*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf); 883*10d63b7dSRichard Lowe append_string(name->string_mb, &string, name->hash.length); 884*10d63b7dSRichard Lowe } 885*10d63b7dSRichard Lowe 886*10d63b7dSRichard Lowe void 887*10d63b7dSRichard Lowe Wstring::init(wchar_t * name, unsigned length) 888*10d63b7dSRichard Lowe { 889*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf); 890*10d63b7dSRichard Lowe append_string(name, &string, length); 891*10d63b7dSRichard Lowe string.buffer.start[length] = 0; 892*10d63b7dSRichard Lowe } 893*10d63b7dSRichard Lowe 894*10d63b7dSRichard Lowe Boolean 895*10d63b7dSRichard Lowe Wstring::equaln(wchar_t * str, unsigned length) 896*10d63b7dSRichard Lowe { 897*10d63b7dSRichard Lowe return (Boolean)IS_WEQUALN(string.buffer.start, str, length); 898*10d63b7dSRichard Lowe } 899*10d63b7dSRichard Lowe 900*10d63b7dSRichard Lowe Boolean 901*10d63b7dSRichard Lowe Wstring::equaln(Wstring * str, unsigned length) 902*10d63b7dSRichard Lowe { 903*10d63b7dSRichard Lowe return (Boolean)IS_WEQUALN(string.buffer.start, str->string.buffer.start, length); 904*10d63b7dSRichard Lowe } 905*10d63b7dSRichard Lowe 906*10d63b7dSRichard Lowe Boolean 907*10d63b7dSRichard Lowe Wstring::equal(wchar_t * str, unsigned off, unsigned length) 908*10d63b7dSRichard Lowe { 909*10d63b7dSRichard Lowe return (Boolean)IS_WEQUALN(string.buffer.start + off, str, length); 910*10d63b7dSRichard Lowe } 911*10d63b7dSRichard Lowe 912*10d63b7dSRichard Lowe Boolean 913*10d63b7dSRichard Lowe Wstring::equal(wchar_t * str, unsigned off) 914*10d63b7dSRichard Lowe { 915*10d63b7dSRichard Lowe return (Boolean)IS_WEQUAL(string.buffer.start + off, str); 916*10d63b7dSRichard Lowe } 917*10d63b7dSRichard Lowe 918*10d63b7dSRichard Lowe Boolean 919*10d63b7dSRichard Lowe Wstring::equal(wchar_t * str) 920*10d63b7dSRichard Lowe { 921*10d63b7dSRichard Lowe return equal(str, 0); 922*10d63b7dSRichard Lowe } 923*10d63b7dSRichard Lowe 924*10d63b7dSRichard Lowe Boolean 925*10d63b7dSRichard Lowe Wstring::equal(Wstring * str, unsigned off, unsigned length) 926*10d63b7dSRichard Lowe { 927*10d63b7dSRichard Lowe return (Boolean)IS_WEQUALN(string.buffer.start + off, str->string.buffer.start, length); 928*10d63b7dSRichard Lowe } 929*10d63b7dSRichard Lowe 930*10d63b7dSRichard Lowe Boolean 931*10d63b7dSRichard Lowe Wstring::equal(Wstring * str) 932*10d63b7dSRichard Lowe { 933*10d63b7dSRichard Lowe return equal(str, 0); 934*10d63b7dSRichard Lowe } 935*10d63b7dSRichard Lowe 936*10d63b7dSRichard Lowe Boolean 937*10d63b7dSRichard Lowe Wstring::equal(Wstring * str, unsigned off) 938*10d63b7dSRichard Lowe { 939*10d63b7dSRichard Lowe return (Boolean)IS_WEQUAL(string.buffer.start + off, str->string.buffer.start); 940*10d63b7dSRichard Lowe } 941*10d63b7dSRichard Lowe 942*10d63b7dSRichard Lowe void 943*10d63b7dSRichard Lowe Wstring::append_to_str(struct _String * str, unsigned off, unsigned length) 944*10d63b7dSRichard Lowe { 945*10d63b7dSRichard Lowe append_string(string.buffer.start + off, str, length); 946*10d63b7dSRichard Lowe } 947*10d63b7dSRichard Lowe 948*10d63b7dSRichard Lowe Name 949*10d63b7dSRichard Lowe Name_set::lookup(const char *key) 950*10d63b7dSRichard Lowe { 951*10d63b7dSRichard Lowe for (entry *node = root; node != 0;) { 952*10d63b7dSRichard Lowe int res = strcmp(key, node->name->string_mb); 953*10d63b7dSRichard Lowe if (res < 0) { 954*10d63b7dSRichard Lowe node = node->left; 955*10d63b7dSRichard Lowe } else if (res > 0) { 956*10d63b7dSRichard Lowe node = node->right; 957*10d63b7dSRichard Lowe } else { 958*10d63b7dSRichard Lowe return node->name; 959*10d63b7dSRichard Lowe } 960*10d63b7dSRichard Lowe } 961*10d63b7dSRichard Lowe return 0; 962*10d63b7dSRichard Lowe } 963*10d63b7dSRichard Lowe 964*10d63b7dSRichard Lowe Name 965*10d63b7dSRichard Lowe Name_set::insert(const char *key, Boolean &found) 966*10d63b7dSRichard Lowe { 967*10d63b7dSRichard Lowe Name name = 0; 968*10d63b7dSRichard Lowe 969*10d63b7dSRichard Lowe if (root != 0) { 970*10d63b7dSRichard Lowe for (entry *node = root; name == 0;) { 971*10d63b7dSRichard Lowe int res = strcmp(key, node->name->string_mb); 972*10d63b7dSRichard Lowe if (res < 0) { 973*10d63b7dSRichard Lowe if (node->left != 0) { 974*10d63b7dSRichard Lowe node = node->left; 975*10d63b7dSRichard Lowe } else { 976*10d63b7dSRichard Lowe found = false; 977*10d63b7dSRichard Lowe name = ALLOC(Name); 978*10d63b7dSRichard Lowe 979*10d63b7dSRichard Lowe node->left = new entry(name, node); 980*10d63b7dSRichard Lowe rebalance(node); 981*10d63b7dSRichard Lowe } 982*10d63b7dSRichard Lowe } else if (res > 0) { 983*10d63b7dSRichard Lowe if (node->right != 0) { 984*10d63b7dSRichard Lowe node = node->right; 985*10d63b7dSRichard Lowe } else { 986*10d63b7dSRichard Lowe found = false; 987*10d63b7dSRichard Lowe name = ALLOC(Name); 988*10d63b7dSRichard Lowe 989*10d63b7dSRichard Lowe node->right = new entry(name, node); 990*10d63b7dSRichard Lowe rebalance(node); 991*10d63b7dSRichard Lowe } 992*10d63b7dSRichard Lowe } else { 993*10d63b7dSRichard Lowe found = true; 994*10d63b7dSRichard Lowe name = node->name; 995*10d63b7dSRichard Lowe } 996*10d63b7dSRichard Lowe } 997*10d63b7dSRichard Lowe } else { 998*10d63b7dSRichard Lowe found = false; 999*10d63b7dSRichard Lowe name = ALLOC(Name); 1000*10d63b7dSRichard Lowe 1001*10d63b7dSRichard Lowe root = new entry(name, 0); 1002*10d63b7dSRichard Lowe } 1003*10d63b7dSRichard Lowe return name; 1004*10d63b7dSRichard Lowe } 1005*10d63b7dSRichard Lowe 1006*10d63b7dSRichard Lowe void 1007*10d63b7dSRichard Lowe Name_set::insert(Name name) { 1008*10d63b7dSRichard Lowe if (root != 0) { 1009*10d63b7dSRichard Lowe for (entry *node = root;;) { 1010*10d63b7dSRichard Lowe int res = strcmp(name->string_mb, node->name->string_mb); 1011*10d63b7dSRichard Lowe if (res < 0) { 1012*10d63b7dSRichard Lowe if (node->left != 0) { 1013*10d63b7dSRichard Lowe node = node->left; 1014*10d63b7dSRichard Lowe } else { 1015*10d63b7dSRichard Lowe node->left = new entry(name, node); 1016*10d63b7dSRichard Lowe rebalance(node); 1017*10d63b7dSRichard Lowe break; 1018*10d63b7dSRichard Lowe } 1019*10d63b7dSRichard Lowe } else if (res > 0) { 1020*10d63b7dSRichard Lowe if (node->right != 0) { 1021*10d63b7dSRichard Lowe node = node->right; 1022*10d63b7dSRichard Lowe } else { 1023*10d63b7dSRichard Lowe node->right = new entry(name, node); 1024*10d63b7dSRichard Lowe rebalance(node); 1025*10d63b7dSRichard Lowe break; 1026*10d63b7dSRichard Lowe } 1027*10d63b7dSRichard Lowe } else { 1028*10d63b7dSRichard Lowe // should be an error: inserting already existing name 1029*10d63b7dSRichard Lowe break; 1030*10d63b7dSRichard Lowe } 1031*10d63b7dSRichard Lowe } 1032*10d63b7dSRichard Lowe } else { 1033*10d63b7dSRichard Lowe root = new entry(name, 0); 1034*10d63b7dSRichard Lowe } 1035*10d63b7dSRichard Lowe } 1036*10d63b7dSRichard Lowe 1037*10d63b7dSRichard Lowe void 1038*10d63b7dSRichard Lowe Name_set::rebalance(Name_set::entry *node) { 1039*10d63b7dSRichard Lowe for (; node != 0; node = node->parent) { 1040*10d63b7dSRichard Lowe entry *right = node->right; 1041*10d63b7dSRichard Lowe entry *left = node->left; 1042*10d63b7dSRichard Lowe 1043*10d63b7dSRichard Lowe unsigned rdepth = (right != 0) ? right->depth : 0; 1044*10d63b7dSRichard Lowe unsigned ldepth = (left != 0) ? left->depth : 0; 1045*10d63b7dSRichard Lowe 1046*10d63b7dSRichard Lowe if (ldepth > rdepth + 1) { 1047*10d63b7dSRichard Lowe if ((node->left = left->right) != 0) { 1048*10d63b7dSRichard Lowe left->right->parent = node; 1049*10d63b7dSRichard Lowe } 1050*10d63b7dSRichard Lowe if ((left->parent = node->parent) != 0) { 1051*10d63b7dSRichard Lowe if (node == node->parent->right) { 1052*10d63b7dSRichard Lowe node->parent->right = left; 1053*10d63b7dSRichard Lowe } else { 1054*10d63b7dSRichard Lowe node->parent->left = left; 1055*10d63b7dSRichard Lowe } 1056*10d63b7dSRichard Lowe } else { 1057*10d63b7dSRichard Lowe root = left; 1058*10d63b7dSRichard Lowe } 1059*10d63b7dSRichard Lowe left->right = node; 1060*10d63b7dSRichard Lowe node->parent = left; 1061*10d63b7dSRichard Lowe 1062*10d63b7dSRichard Lowe node->setup_depth(); 1063*10d63b7dSRichard Lowe node = left; 1064*10d63b7dSRichard Lowe } else if (rdepth > ldepth + 1) { 1065*10d63b7dSRichard Lowe if ((node->right = right->left) != 0) { 1066*10d63b7dSRichard Lowe right->left->parent = node; 1067*10d63b7dSRichard Lowe } 1068*10d63b7dSRichard Lowe if ((right->parent = node->parent) != 0) { 1069*10d63b7dSRichard Lowe if (node == node->parent->right) { 1070*10d63b7dSRichard Lowe node->parent->right = right; 1071*10d63b7dSRichard Lowe } else { 1072*10d63b7dSRichard Lowe node->parent->left = right; 1073*10d63b7dSRichard Lowe } 1074*10d63b7dSRichard Lowe } else { 1075*10d63b7dSRichard Lowe root = right; 1076*10d63b7dSRichard Lowe } 1077*10d63b7dSRichard Lowe right->left = node; 1078*10d63b7dSRichard Lowe node->parent = right; 1079*10d63b7dSRichard Lowe 1080*10d63b7dSRichard Lowe node->setup_depth(); 1081*10d63b7dSRichard Lowe node = right; 1082*10d63b7dSRichard Lowe } 1083*10d63b7dSRichard Lowe node->setup_depth(); 1084*10d63b7dSRichard Lowe } 1085*10d63b7dSRichard Lowe } 1086*10d63b7dSRichard Lowe 1087*10d63b7dSRichard Lowe Name_set::iterator 1088*10d63b7dSRichard Lowe Name_set::begin() const { 1089*10d63b7dSRichard Lowe for (entry *node = root; node != 0; node = node->left) { 1090*10d63b7dSRichard Lowe if (node->left == 0) { 1091*10d63b7dSRichard Lowe return iterator(node); 1092*10d63b7dSRichard Lowe } 1093*10d63b7dSRichard Lowe } 1094*10d63b7dSRichard Lowe return iterator(); 1095*10d63b7dSRichard Lowe } 1096*10d63b7dSRichard Lowe 1097*10d63b7dSRichard Lowe Name_set::iterator& 1098*10d63b7dSRichard Lowe Name_set::iterator::operator++() { 1099*10d63b7dSRichard Lowe if (node != 0) { 1100*10d63b7dSRichard Lowe if (node->right != 0) { 1101*10d63b7dSRichard Lowe node = node->right; 1102*10d63b7dSRichard Lowe while (node->left != 0) { 1103*10d63b7dSRichard Lowe node = node->left; 1104*10d63b7dSRichard Lowe } 1105*10d63b7dSRichard Lowe } else { 1106*10d63b7dSRichard Lowe while ((node->parent != 0) && (node->parent->right == node)) { 1107*10d63b7dSRichard Lowe node = node->parent; 1108*10d63b7dSRichard Lowe } 1109*10d63b7dSRichard Lowe node = node->parent; 1110*10d63b7dSRichard Lowe } 1111*10d63b7dSRichard Lowe } 1112*10d63b7dSRichard Lowe return *this; 1113*10d63b7dSRichard Lowe } 1114