110d63b7dSRichard Lowe /* 210d63b7dSRichard Lowe * CDDL HEADER START 310d63b7dSRichard Lowe * 410d63b7dSRichard Lowe * The contents of this file are subject to the terms of the 510d63b7dSRichard Lowe * Common Development and Distribution License (the "License"). 610d63b7dSRichard Lowe * You may not use this file except in compliance with the License. 710d63b7dSRichard Lowe * 810d63b7dSRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 910d63b7dSRichard Lowe * or http://www.opensolaris.org/os/licensing. 1010d63b7dSRichard Lowe * See the License for the specific language governing permissions 1110d63b7dSRichard Lowe * and limitations under the License. 1210d63b7dSRichard Lowe * 1310d63b7dSRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each 1410d63b7dSRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1510d63b7dSRichard Lowe * If applicable, add the following below this CDDL HEADER, with the 1610d63b7dSRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying 1710d63b7dSRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner] 1810d63b7dSRichard Lowe * 1910d63b7dSRichard Lowe * CDDL HEADER END 2010d63b7dSRichard Lowe */ 2110d63b7dSRichard Lowe /* 2210d63b7dSRichard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 2310d63b7dSRichard Lowe * Use is subject to license terms. 2410d63b7dSRichard Lowe */ 2510d63b7dSRichard Lowe 2610d63b7dSRichard Lowe 2710d63b7dSRichard Lowe /* 2810d63b7dSRichard Lowe * misc.cc 2910d63b7dSRichard Lowe * 3010d63b7dSRichard Lowe * This file contains various unclassified routines. Some main groups: 3110d63b7dSRichard Lowe * getname 3210d63b7dSRichard Lowe * Memory allocation 3310d63b7dSRichard Lowe * String handling 3410d63b7dSRichard Lowe * Property handling 3510d63b7dSRichard Lowe * Error message handling 3610d63b7dSRichard Lowe * Make internal state dumping 3710d63b7dSRichard Lowe * main routine support 3810d63b7dSRichard Lowe */ 3910d63b7dSRichard Lowe 4010d63b7dSRichard Lowe /* 4110d63b7dSRichard Lowe * Included files 4210d63b7dSRichard Lowe */ 4310d63b7dSRichard Lowe #include <bsd/bsd.h> /* bsd_signal() */ 4410d63b7dSRichard Lowe #include <mksh/i18n.h> /* get_char_semantics_value() */ 4510d63b7dSRichard Lowe #include <mksh/misc.h> 4610d63b7dSRichard Lowe #include <stdarg.h> /* va_list, va_start(), va_end() */ 4710d63b7dSRichard Lowe #include <stdlib.h> /* mbstowcs() */ 4810d63b7dSRichard Lowe #include <sys/signal.h> /* SIG_DFL */ 4910d63b7dSRichard Lowe #include <sys/wait.h> /* wait() */ 5010d63b7dSRichard Lowe 5110d63b7dSRichard Lowe #include <string.h> /* strerror() */ 5210d63b7dSRichard Lowe #include <libintl.h> 5310d63b7dSRichard Lowe 5410d63b7dSRichard Lowe 5510d63b7dSRichard Lowe /* 5610d63b7dSRichard Lowe * Defined macros 5710d63b7dSRichard Lowe */ 5810d63b7dSRichard Lowe 5910d63b7dSRichard Lowe /* 6010d63b7dSRichard Lowe * typedefs & structs 6110d63b7dSRichard Lowe */ 6210d63b7dSRichard Lowe 6310d63b7dSRichard Lowe /* 6410d63b7dSRichard Lowe * Static variables 6510d63b7dSRichard Lowe */ 6610d63b7dSRichard Lowe extern "C" { 6710d63b7dSRichard Lowe void (*sigivalue)(int) = SIG_DFL; 6810d63b7dSRichard Lowe void (*sigqvalue)(int) = SIG_DFL; 6910d63b7dSRichard Lowe void (*sigtvalue)(int) = SIG_DFL; 7010d63b7dSRichard Lowe void (*sighvalue)(int) = SIG_DFL; 7110d63b7dSRichard Lowe } 7210d63b7dSRichard Lowe 7310d63b7dSRichard Lowe long getname_bytes_count = 0; 7410d63b7dSRichard Lowe long getname_names_count = 0; 7510d63b7dSRichard Lowe long getname_struct_count = 0; 7610d63b7dSRichard Lowe 7710d63b7dSRichard Lowe long freename_bytes_count = 0; 7810d63b7dSRichard Lowe long freename_names_count = 0; 7910d63b7dSRichard Lowe long freename_struct_count = 0; 8010d63b7dSRichard Lowe 8110d63b7dSRichard Lowe long expandstring_count = 0; 8210d63b7dSRichard Lowe long getwstring_count = 0; 8310d63b7dSRichard Lowe 8410d63b7dSRichard Lowe /* 8510d63b7dSRichard Lowe * File table of contents 8610d63b7dSRichard Lowe */ 8710d63b7dSRichard Lowe static void expand_string(register String string, register int length); 8810d63b7dSRichard Lowe 8910d63b7dSRichard Lowe #define FATAL_ERROR_MSG_SIZE 200 9010d63b7dSRichard Lowe 9110d63b7dSRichard Lowe /* 9210d63b7dSRichard Lowe * getmem(size) 9310d63b7dSRichard Lowe * 9410d63b7dSRichard Lowe * malloc() version that checks the returned value. 9510d63b7dSRichard Lowe * 9610d63b7dSRichard Lowe * Return value: 9710d63b7dSRichard Lowe * The memory chunk we allocated 9810d63b7dSRichard Lowe * 9910d63b7dSRichard Lowe * Parameters: 10010d63b7dSRichard Lowe * size The size of the chunk we need 10110d63b7dSRichard Lowe * 10210d63b7dSRichard Lowe * Global variables used: 10310d63b7dSRichard Lowe */ 10410d63b7dSRichard Lowe char * 105*356ba08cSToomas Soome getmem(size_t size) 10610d63b7dSRichard Lowe { 107*356ba08cSToomas Soome char *result = (char *)malloc(size); 10810d63b7dSRichard Lowe if (result == NULL) { 109*356ba08cSToomas Soome (void) fprintf(stderr, "*** Error: malloc(%d) failed: %s\n%s", 110*356ba08cSToomas Soome size, strerror(errno), 111*356ba08cSToomas Soome gettext("mksh: Fatal error: Out of memory\n")); 11210d63b7dSRichard Lowe exit(1); 11310d63b7dSRichard Lowe } 114*356ba08cSToomas Soome return (result); 11510d63b7dSRichard Lowe } 11610d63b7dSRichard Lowe 11710d63b7dSRichard Lowe /* 11810d63b7dSRichard Lowe * retmem(p) 11910d63b7dSRichard Lowe * 12010d63b7dSRichard Lowe * Cover funtion for free() to make it possible to insert advises. 12110d63b7dSRichard Lowe * 12210d63b7dSRichard Lowe * Parameters: 12310d63b7dSRichard Lowe * p The memory block to free 12410d63b7dSRichard Lowe * 12510d63b7dSRichard Lowe * Global variables used: 12610d63b7dSRichard Lowe */ 12710d63b7dSRichard Lowe void 12810d63b7dSRichard Lowe retmem(wchar_t *p) 12910d63b7dSRichard Lowe { 13010d63b7dSRichard Lowe (void) free((char *) p); 13110d63b7dSRichard Lowe } 13210d63b7dSRichard Lowe 13310d63b7dSRichard Lowe void 13410d63b7dSRichard Lowe retmem_mb(caddr_t p) 13510d63b7dSRichard Lowe { 13610d63b7dSRichard Lowe (void) free(p); 13710d63b7dSRichard Lowe } 13810d63b7dSRichard Lowe 13910d63b7dSRichard Lowe /* 14010d63b7dSRichard Lowe * getname_fn(name, len, dont_enter) 14110d63b7dSRichard Lowe * 14210d63b7dSRichard Lowe * Hash a name string to the corresponding nameblock. 14310d63b7dSRichard Lowe * 14410d63b7dSRichard Lowe * Return value: 14510d63b7dSRichard Lowe * The Name block for the string 14610d63b7dSRichard Lowe * 14710d63b7dSRichard Lowe * Parameters: 14810d63b7dSRichard Lowe * name The string we want to internalize 14910d63b7dSRichard Lowe * len The length of that string 15010d63b7dSRichard Lowe * dont_enter Don't enter the name if it does not exist 15110d63b7dSRichard Lowe * 15210d63b7dSRichard Lowe * Global variables used: 15310d63b7dSRichard Lowe * funny The vector of semantic tags for characters 15410d63b7dSRichard Lowe * hashtab The hashtable used for the nametable 15510d63b7dSRichard Lowe */ 15610d63b7dSRichard Lowe Name 15710d63b7dSRichard Lowe getname_fn(wchar_t *name, register int len, register Boolean dont_enter, register Boolean * foundp) 15810d63b7dSRichard Lowe { 15910d63b7dSRichard Lowe register int length; 16010d63b7dSRichard Lowe register wchar_t *cap = name; 16110d63b7dSRichard Lowe register Name np; 16210d63b7dSRichard Lowe static Name_rec empty_Name; 16310d63b7dSRichard Lowe char *tmp_mbs_buffer = NULL; 16410d63b7dSRichard Lowe char *mbs_name = mbs_buffer; 16510d63b7dSRichard Lowe 16610d63b7dSRichard Lowe /* 16710d63b7dSRichard Lowe * First figure out how long the string is. 16810d63b7dSRichard Lowe * If the len argument is -1 we count the chars here. 16910d63b7dSRichard Lowe */ 17010d63b7dSRichard Lowe if (len == FIND_LENGTH) { 17110d63b7dSRichard Lowe length = wcslen(name); 17210d63b7dSRichard Lowe } else { 17310d63b7dSRichard Lowe length = len; 17410d63b7dSRichard Lowe } 17510d63b7dSRichard Lowe 17610d63b7dSRichard Lowe Wstring ws; 17710d63b7dSRichard Lowe ws.init(name, length); 17810d63b7dSRichard Lowe if (length >= MAXPATHLEN) { 17910d63b7dSRichard Lowe mbs_name = tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1); 18010d63b7dSRichard Lowe } 18110d63b7dSRichard Lowe (void) wcstombs(mbs_name, ws.get_string(), (length * MB_LEN_MAX) + 1); 18210d63b7dSRichard Lowe 18310d63b7dSRichard Lowe /* Look for the string */ 18410d63b7dSRichard Lowe if (dont_enter || (foundp != 0)) { 18510d63b7dSRichard Lowe np = hashtab.lookup(mbs_name); 18610d63b7dSRichard Lowe if (foundp != 0) { 18710d63b7dSRichard Lowe *foundp = (np != 0) ? true : false; 18810d63b7dSRichard Lowe } 18910d63b7dSRichard Lowe if ((np != 0) || dont_enter) { 19010d63b7dSRichard Lowe if(tmp_mbs_buffer != NULL) { 19110d63b7dSRichard Lowe retmem_mb(tmp_mbs_buffer); 19210d63b7dSRichard Lowe } 19310d63b7dSRichard Lowe return np; 19410d63b7dSRichard Lowe } else { 19510d63b7dSRichard Lowe np = ALLOC(Name); 19610d63b7dSRichard Lowe } 19710d63b7dSRichard Lowe } else { 19810d63b7dSRichard Lowe Boolean found; 19910d63b7dSRichard Lowe np = hashtab.insert(mbs_name, found); 20010d63b7dSRichard Lowe if (found) { 20110d63b7dSRichard Lowe if(tmp_mbs_buffer != NULL) { 20210d63b7dSRichard Lowe retmem_mb(tmp_mbs_buffer); 20310d63b7dSRichard Lowe } 20410d63b7dSRichard Lowe return np; 20510d63b7dSRichard Lowe } 20610d63b7dSRichard Lowe } 20710d63b7dSRichard Lowe getname_struct_count += sizeof(struct _Name); 20810d63b7dSRichard Lowe *np = empty_Name; 20910d63b7dSRichard Lowe 21010d63b7dSRichard Lowe np->string_mb = strdup(mbs_name); 21110d63b7dSRichard Lowe if(tmp_mbs_buffer != NULL) { 21210d63b7dSRichard Lowe retmem_mb(tmp_mbs_buffer); 21310d63b7dSRichard Lowe mbs_name = tmp_mbs_buffer = NULL; 21410d63b7dSRichard Lowe } 21510d63b7dSRichard Lowe getname_bytes_count += strlen(np->string_mb) + 1; 21610d63b7dSRichard Lowe /* Fill in the new Name */ 21710d63b7dSRichard Lowe np->stat.time = file_no_time; 21810d63b7dSRichard Lowe np->hash.length = length; 21910d63b7dSRichard Lowe /* Scan the namestring to classify it */ 22010d63b7dSRichard Lowe for (cap = name, len = 0; --length >= 0;) { 22110d63b7dSRichard Lowe len |= get_char_semantics_value(*cap++); 22210d63b7dSRichard Lowe } 22310d63b7dSRichard Lowe np->dollar = BOOLEAN((len & (int) dollar_sem) != 0); 22410d63b7dSRichard Lowe np->meta = BOOLEAN((len & (int) meta_sem) != 0); 22510d63b7dSRichard Lowe np->percent = BOOLEAN((len & (int) percent_sem) != 0); 22610d63b7dSRichard Lowe np->wildcard = BOOLEAN((len & (int) wildcard_sem) != 0); 22710d63b7dSRichard Lowe np->colon = BOOLEAN((len & (int) colon_sem) != 0); 22810d63b7dSRichard Lowe np->parenleft = BOOLEAN((len & (int) parenleft_sem) != 0); 22910d63b7dSRichard Lowe getname_names_count++; 23010d63b7dSRichard Lowe return np; 23110d63b7dSRichard Lowe } 23210d63b7dSRichard Lowe 23310d63b7dSRichard Lowe void 23410d63b7dSRichard Lowe store_name(Name name) 23510d63b7dSRichard Lowe { 23610d63b7dSRichard Lowe hashtab.insert(name); 23710d63b7dSRichard Lowe } 23810d63b7dSRichard Lowe 23910d63b7dSRichard Lowe void 24010d63b7dSRichard Lowe free_name(Name name) 24110d63b7dSRichard Lowe { 24210d63b7dSRichard Lowe freename_names_count++; 24310d63b7dSRichard Lowe freename_struct_count += sizeof(struct _Name); 24410d63b7dSRichard Lowe freename_bytes_count += strlen(name->string_mb) + 1; 24510d63b7dSRichard Lowe retmem_mb(name->string_mb); 24610d63b7dSRichard Lowe for (Property next, p = name->prop; p != NULL; p = next) { 24710d63b7dSRichard Lowe next = p->next; 24810d63b7dSRichard Lowe free(p); 24910d63b7dSRichard Lowe } 25010d63b7dSRichard Lowe free(name); 25110d63b7dSRichard Lowe } 25210d63b7dSRichard Lowe 25310d63b7dSRichard Lowe /* 25410d63b7dSRichard Lowe * enable_interrupt(handler) 25510d63b7dSRichard Lowe * 25610d63b7dSRichard Lowe * This routine sets a new interrupt handler for the signals make 25710d63b7dSRichard Lowe * wants to deal with. 25810d63b7dSRichard Lowe * 25910d63b7dSRichard Lowe * Parameters: 26010d63b7dSRichard Lowe * handler The function installed as interrupt handler 26110d63b7dSRichard Lowe * 26210d63b7dSRichard Lowe * Static variables used: 26310d63b7dSRichard Lowe * sigivalue The original signal handler 26410d63b7dSRichard Lowe * sigqvalue The original signal handler 26510d63b7dSRichard Lowe * sigtvalue The original signal handler 26610d63b7dSRichard Lowe * sighvalue The original signal handler 26710d63b7dSRichard Lowe */ 26810d63b7dSRichard Lowe void 26910d63b7dSRichard Lowe enable_interrupt(register void (*handler) (int)) 27010d63b7dSRichard Lowe { 27110d63b7dSRichard Lowe if (sigivalue != SIG_IGN) { 27210d63b7dSRichard Lowe (void) bsd_signal(SIGINT, (SIG_PF) handler); 27310d63b7dSRichard Lowe } 27410d63b7dSRichard Lowe if (sigqvalue != SIG_IGN) { 27510d63b7dSRichard Lowe (void) bsd_signal(SIGQUIT, (SIG_PF) handler); 27610d63b7dSRichard Lowe } 27710d63b7dSRichard Lowe if (sigtvalue != SIG_IGN) { 27810d63b7dSRichard Lowe (void) bsd_signal(SIGTERM, (SIG_PF) handler); 27910d63b7dSRichard Lowe } 28010d63b7dSRichard Lowe if (sighvalue != SIG_IGN) { 28110d63b7dSRichard Lowe (void) bsd_signal(SIGHUP, (SIG_PF) handler); 28210d63b7dSRichard Lowe } 28310d63b7dSRichard Lowe } 28410d63b7dSRichard Lowe 28510d63b7dSRichard Lowe /* 28610d63b7dSRichard Lowe * setup_char_semantics() 28710d63b7dSRichard Lowe * 28810d63b7dSRichard Lowe * Load the vector char_semantics[] with lexical markers 28910d63b7dSRichard Lowe * 29010d63b7dSRichard Lowe * Parameters: 29110d63b7dSRichard Lowe * 29210d63b7dSRichard Lowe * Global variables used: 29310d63b7dSRichard Lowe * char_semantics The vector of character semantics that we set 29410d63b7dSRichard Lowe */ 29510d63b7dSRichard Lowe void 29610d63b7dSRichard Lowe setup_char_semantics(void) 29710d63b7dSRichard Lowe { 29810d63b7dSRichard Lowe const char *s; 29910d63b7dSRichard Lowe wchar_t wc_buffer[1]; 30010d63b7dSRichard Lowe int entry; 30110d63b7dSRichard Lowe 30210d63b7dSRichard Lowe if (svr4) { 30310d63b7dSRichard Lowe s = "@-"; 30410d63b7dSRichard Lowe } else { 30510d63b7dSRichard Lowe s = "=@-?!+"; 30610d63b7dSRichard Lowe } 30710d63b7dSRichard Lowe for (s; MBTOWC(wc_buffer, s); s++) { 30810d63b7dSRichard Lowe entry = get_char_semantics_entry(*wc_buffer); 30910d63b7dSRichard Lowe char_semantics[entry] |= (int) command_prefix_sem; 31010d63b7dSRichard Lowe } 31110d63b7dSRichard Lowe char_semantics[dollar_char_entry] |= (int) dollar_sem; 31210d63b7dSRichard Lowe for (s = "#|=^();&<>*?[]:$`'\"\\\n"; MBTOWC(wc_buffer, s); s++) { 31310d63b7dSRichard Lowe entry = get_char_semantics_entry(*wc_buffer); 31410d63b7dSRichard Lowe char_semantics[entry] |= (int) meta_sem; 31510d63b7dSRichard Lowe } 31610d63b7dSRichard Lowe char_semantics[percent_char_entry] |= (int) percent_sem; 31710d63b7dSRichard Lowe for (s = "@*<%?^"; MBTOWC(wc_buffer, s); s++) { 31810d63b7dSRichard Lowe entry = get_char_semantics_entry(*wc_buffer); 31910d63b7dSRichard Lowe char_semantics[entry] |= (int) special_macro_sem; 32010d63b7dSRichard Lowe } 32110d63b7dSRichard Lowe for (s = "?[*"; MBTOWC(wc_buffer, s); s++) { 32210d63b7dSRichard Lowe entry = get_char_semantics_entry(*wc_buffer); 32310d63b7dSRichard Lowe char_semantics[entry] |= (int) wildcard_sem; 32410d63b7dSRichard Lowe } 32510d63b7dSRichard Lowe char_semantics[colon_char_entry] |= (int) colon_sem; 32610d63b7dSRichard Lowe char_semantics[parenleft_char_entry] |= (int) parenleft_sem; 32710d63b7dSRichard Lowe } 32810d63b7dSRichard Lowe 32910d63b7dSRichard Lowe /* 33010d63b7dSRichard Lowe * errmsg(errnum) 33110d63b7dSRichard Lowe * 33210d63b7dSRichard Lowe * Return the error message for a system call error 33310d63b7dSRichard Lowe * 33410d63b7dSRichard Lowe * Return value: 33510d63b7dSRichard Lowe * An error message string 33610d63b7dSRichard Lowe * 33710d63b7dSRichard Lowe * Parameters: 33810d63b7dSRichard Lowe * errnum The number of the error we want to describe 33910d63b7dSRichard Lowe */ 34010d63b7dSRichard Lowe char * 34110d63b7dSRichard Lowe errmsg(int errnum) 34210d63b7dSRichard Lowe { 343*356ba08cSToomas Soome char *msg; 344*356ba08cSToomas Soome char *errbuf; 345*356ba08cSToomas Soome 346*356ba08cSToomas Soome errno = 0; 347*356ba08cSToomas Soome msg = strerror(errnum); 348*356ba08cSToomas Soome if (errno == EINVAL) { 349*356ba08cSToomas Soome size_t size = 6 + 1 + 11 + 1; 350*356ba08cSToomas Soome errbuf = getmem(size); 351*356ba08cSToomas Soome (void) snprintf(errbuf, size, gettext("Error %d"), errnum); 352*356ba08cSToomas Soome return (errbuf); 35310d63b7dSRichard Lowe } 354*356ba08cSToomas Soome return (msg); 35510d63b7dSRichard Lowe } 35610d63b7dSRichard Lowe 35710d63b7dSRichard Lowe static char static_buf[MAXPATHLEN*3]; 35810d63b7dSRichard Lowe 35910d63b7dSRichard Lowe /* 36010d63b7dSRichard Lowe * fatal_mksh(format, args...) 36110d63b7dSRichard Lowe * 36210d63b7dSRichard Lowe * Print a message and die 36310d63b7dSRichard Lowe * 36410d63b7dSRichard Lowe * Parameters: 36510d63b7dSRichard Lowe * format printf type format string 36610d63b7dSRichard Lowe * args Arguments to match the format 36710d63b7dSRichard Lowe */ 36810d63b7dSRichard Lowe /*VARARGS*/ 36910d63b7dSRichard Lowe void 37010d63b7dSRichard Lowe fatal_mksh(const char *message, ...) 37110d63b7dSRichard Lowe { 37210d63b7dSRichard Lowe va_list args; 37310d63b7dSRichard Lowe char *buf = static_buf; 37410d63b7dSRichard Lowe char *mksh_fat_err = gettext("mksh: Fatal error: "); 37510d63b7dSRichard Lowe char *cur_wrk_dir = gettext("Current working directory: "); 37610d63b7dSRichard Lowe int mksh_fat_err_len = strlen(mksh_fat_err); 37710d63b7dSRichard Lowe 37810d63b7dSRichard Lowe va_start(args, message); 37910d63b7dSRichard Lowe (void) fflush(stdout); 38010d63b7dSRichard Lowe (void) strcpy(buf, mksh_fat_err); 38110d63b7dSRichard Lowe size_t buf_len = vsnprintf(static_buf + mksh_fat_err_len, 38210d63b7dSRichard Lowe sizeof(static_buf) - mksh_fat_err_len, 38310d63b7dSRichard Lowe message, args) 38410d63b7dSRichard Lowe + mksh_fat_err_len 38510d63b7dSRichard Lowe + strlen(cur_wrk_dir) 38610d63b7dSRichard Lowe + strlen(get_current_path_mksh()) 38710d63b7dSRichard Lowe + 3; // "\n\n" 38810d63b7dSRichard Lowe va_end(args); 38910d63b7dSRichard Lowe if (buf_len >= sizeof(static_buf)) { 39010d63b7dSRichard Lowe buf = getmem(buf_len); 39110d63b7dSRichard Lowe (void) strcpy(buf, mksh_fat_err); 39210d63b7dSRichard Lowe va_start(args, message); 39310d63b7dSRichard Lowe (void) vsprintf(buf + mksh_fat_err_len, message, args); 39410d63b7dSRichard Lowe va_end(args); 39510d63b7dSRichard Lowe } 39610d63b7dSRichard Lowe (void) strcat(buf, "\n"); 39710d63b7dSRichard Lowe /* 39810d63b7dSRichard Lowe if (report_pwd) { 39910d63b7dSRichard Lowe */ 40010d63b7dSRichard Lowe if (1) { 40110d63b7dSRichard Lowe (void) strcat(buf, cur_wrk_dir); 40210d63b7dSRichard Lowe (void) strcat(buf, get_current_path_mksh()); 40310d63b7dSRichard Lowe (void) strcat(buf, "\n"); 40410d63b7dSRichard Lowe } 40510d63b7dSRichard Lowe (void) fputs(buf, stderr); 40610d63b7dSRichard Lowe (void) fflush(stderr); 40710d63b7dSRichard Lowe if (buf != static_buf) { 40810d63b7dSRichard Lowe retmem_mb(buf); 40910d63b7dSRichard Lowe } 41010d63b7dSRichard Lowe exit_status = 1; 41110d63b7dSRichard Lowe exit(1); 41210d63b7dSRichard Lowe } 41310d63b7dSRichard Lowe 41410d63b7dSRichard Lowe /* 41510d63b7dSRichard Lowe * fatal_reader_mksh(format, args...) 41610d63b7dSRichard Lowe * 41710d63b7dSRichard Lowe * Parameters: 41810d63b7dSRichard Lowe * format printf style format string 41910d63b7dSRichard Lowe * args arguments to match the format 42010d63b7dSRichard Lowe */ 42110d63b7dSRichard Lowe /*VARARGS*/ 42210d63b7dSRichard Lowe void 42310d63b7dSRichard Lowe fatal_reader_mksh(const char * pattern, ...) 42410d63b7dSRichard Lowe { 42510d63b7dSRichard Lowe va_list args; 42610d63b7dSRichard Lowe char message[1000]; 42710d63b7dSRichard Lowe 42810d63b7dSRichard Lowe va_start(args, pattern); 42910d63b7dSRichard Lowe /* 43010d63b7dSRichard Lowe if (file_being_read != NULL) { 43110d63b7dSRichard Lowe WCSTOMBS(mbs_buffer, file_being_read); 43210d63b7dSRichard Lowe if (line_number != 0) { 43310d63b7dSRichard Lowe (void) sprintf(message, 43410d63b7dSRichard Lowe gettext("%s, line %d: %s"), 43510d63b7dSRichard Lowe mbs_buffer, 43610d63b7dSRichard Lowe line_number, 43710d63b7dSRichard Lowe pattern); 43810d63b7dSRichard Lowe } else { 43910d63b7dSRichard Lowe (void) sprintf(message, 44010d63b7dSRichard Lowe "%s: %s", 44110d63b7dSRichard Lowe mbs_buffer, 44210d63b7dSRichard Lowe pattern); 44310d63b7dSRichard Lowe } 44410d63b7dSRichard Lowe pattern = message; 44510d63b7dSRichard Lowe } 44610d63b7dSRichard Lowe */ 44710d63b7dSRichard Lowe 44810d63b7dSRichard Lowe (void) fflush(stdout); 44910d63b7dSRichard Lowe (void) fprintf(stderr, gettext("mksh: Fatal error in reader: ")); 45010d63b7dSRichard Lowe (void) vfprintf(stderr, pattern, args); 45110d63b7dSRichard Lowe (void) fprintf(stderr, "\n"); 45210d63b7dSRichard Lowe va_end(args); 45310d63b7dSRichard Lowe 45410d63b7dSRichard Lowe /* 45510d63b7dSRichard Lowe if (temp_file_name != NULL) { 45610d63b7dSRichard Lowe (void) fprintf(stderr, 45710d63b7dSRichard Lowe gettext("mksh: Temp-file %s not removed\n"), 45810d63b7dSRichard Lowe temp_file_name->string_mb); 45910d63b7dSRichard Lowe temp_file_name = NULL; 46010d63b7dSRichard Lowe } 46110d63b7dSRichard Lowe */ 46210d63b7dSRichard Lowe 46310d63b7dSRichard Lowe /* 46410d63b7dSRichard Lowe if (report_pwd) { 46510d63b7dSRichard Lowe */ 46610d63b7dSRichard Lowe if (1) { 46710d63b7dSRichard Lowe (void) fprintf(stderr, 46810d63b7dSRichard Lowe gettext("Current working directory %s\n"), 46910d63b7dSRichard Lowe get_current_path_mksh()); 47010d63b7dSRichard Lowe } 47110d63b7dSRichard Lowe (void) fflush(stderr); 47210d63b7dSRichard Lowe exit_status = 1; 47310d63b7dSRichard Lowe exit(1); 47410d63b7dSRichard Lowe } 47510d63b7dSRichard Lowe 47610d63b7dSRichard Lowe /* 47710d63b7dSRichard Lowe * warning_mksh(format, args...) 47810d63b7dSRichard Lowe * 47910d63b7dSRichard Lowe * Print a message and continue. 48010d63b7dSRichard Lowe * 48110d63b7dSRichard Lowe * Parameters: 48210d63b7dSRichard Lowe * format printf type format string 48310d63b7dSRichard Lowe * args Arguments to match the format 48410d63b7dSRichard Lowe */ 48510d63b7dSRichard Lowe /*VARARGS*/ 48610d63b7dSRichard Lowe void 48710d63b7dSRichard Lowe warning_mksh(char * message, ...) 48810d63b7dSRichard Lowe { 48910d63b7dSRichard Lowe va_list args; 49010d63b7dSRichard Lowe 49110d63b7dSRichard Lowe va_start(args, message); 49210d63b7dSRichard Lowe (void) fflush(stdout); 49310d63b7dSRichard Lowe (void) fprintf(stderr, gettext("mksh: Warning: ")); 49410d63b7dSRichard Lowe (void) vfprintf(stderr, message, args); 49510d63b7dSRichard Lowe (void) fprintf(stderr, "\n"); 49610d63b7dSRichard Lowe va_end(args); 49710d63b7dSRichard Lowe /* 49810d63b7dSRichard Lowe if (report_pwd) { 49910d63b7dSRichard Lowe */ 50010d63b7dSRichard Lowe if (1) { 50110d63b7dSRichard Lowe (void) fprintf(stderr, 50210d63b7dSRichard Lowe gettext("Current working directory %s\n"), 50310d63b7dSRichard Lowe get_current_path_mksh()); 50410d63b7dSRichard Lowe } 50510d63b7dSRichard Lowe (void) fflush(stderr); 50610d63b7dSRichard Lowe } 50710d63b7dSRichard Lowe 50810d63b7dSRichard Lowe /* 50910d63b7dSRichard Lowe * get_current_path_mksh() 51010d63b7dSRichard Lowe * 51110d63b7dSRichard Lowe * Stuff current_path with the current path if it isnt there already. 51210d63b7dSRichard Lowe * 51310d63b7dSRichard Lowe * Parameters: 51410d63b7dSRichard Lowe * 51510d63b7dSRichard Lowe * Global variables used: 51610d63b7dSRichard Lowe */ 51710d63b7dSRichard Lowe char * 51810d63b7dSRichard Lowe get_current_path_mksh(void) 51910d63b7dSRichard Lowe { 52010d63b7dSRichard Lowe char pwd[(MAXPATHLEN * MB_LEN_MAX)]; 52110d63b7dSRichard Lowe static char *current_path; 52210d63b7dSRichard Lowe 52310d63b7dSRichard Lowe if (current_path == NULL) { 52410d63b7dSRichard Lowe getcwd(pwd, sizeof(pwd)); 52510d63b7dSRichard Lowe if (pwd[0] == (int) nul_char) { 52610d63b7dSRichard Lowe pwd[0] = (int) slash_char; 52710d63b7dSRichard Lowe pwd[1] = (int) nul_char; 52810d63b7dSRichard Lowe } 52910d63b7dSRichard Lowe current_path = strdup(pwd); 53010d63b7dSRichard Lowe } 53110d63b7dSRichard Lowe return current_path; 53210d63b7dSRichard Lowe } 53310d63b7dSRichard Lowe 53410d63b7dSRichard Lowe /* 53510d63b7dSRichard Lowe * append_prop(target, type) 53610d63b7dSRichard Lowe * 53710d63b7dSRichard Lowe * Create a new property and append it to the property list of a Name. 53810d63b7dSRichard Lowe * 53910d63b7dSRichard Lowe * Return value: 54010d63b7dSRichard Lowe * A new property block for the target 54110d63b7dSRichard Lowe * 54210d63b7dSRichard Lowe * Parameters: 54310d63b7dSRichard Lowe * target The target that wants a new property 54410d63b7dSRichard Lowe * type The type of property being requested 54510d63b7dSRichard Lowe * 54610d63b7dSRichard Lowe * Global variables used: 54710d63b7dSRichard Lowe */ 54810d63b7dSRichard Lowe Property 54910d63b7dSRichard Lowe append_prop(register Name target, register Property_id type) 55010d63b7dSRichard Lowe { 55110d63b7dSRichard Lowe register Property *insert = &target->prop; 55210d63b7dSRichard Lowe register Property prop = *insert; 55310d63b7dSRichard Lowe register int size; 55410d63b7dSRichard Lowe 55510d63b7dSRichard Lowe switch (type) { 55610d63b7dSRichard Lowe case conditional_prop: 55710d63b7dSRichard Lowe size = sizeof (struct Conditional); 55810d63b7dSRichard Lowe break; 55910d63b7dSRichard Lowe case line_prop: 56010d63b7dSRichard Lowe size = sizeof (struct Line); 56110d63b7dSRichard Lowe break; 56210d63b7dSRichard Lowe case macro_prop: 56310d63b7dSRichard Lowe size = sizeof (struct _Macro); 56410d63b7dSRichard Lowe break; 56510d63b7dSRichard Lowe case makefile_prop: 56610d63b7dSRichard Lowe size = sizeof (struct Makefile); 56710d63b7dSRichard Lowe break; 56810d63b7dSRichard Lowe case member_prop: 56910d63b7dSRichard Lowe size = sizeof (struct Member); 57010d63b7dSRichard Lowe break; 57110d63b7dSRichard Lowe case recursive_prop: 57210d63b7dSRichard Lowe size = sizeof (struct Recursive); 57310d63b7dSRichard Lowe break; 57410d63b7dSRichard Lowe case sccs_prop: 57510d63b7dSRichard Lowe size = sizeof (struct Sccs); 57610d63b7dSRichard Lowe break; 57710d63b7dSRichard Lowe case suffix_prop: 57810d63b7dSRichard Lowe size = sizeof (struct Suffix); 57910d63b7dSRichard Lowe break; 58010d63b7dSRichard Lowe case target_prop: 58110d63b7dSRichard Lowe size = sizeof (struct Target); 58210d63b7dSRichard Lowe break; 58310d63b7dSRichard Lowe case time_prop: 58410d63b7dSRichard Lowe size = sizeof (struct STime); 58510d63b7dSRichard Lowe break; 58610d63b7dSRichard Lowe case vpath_alias_prop: 58710d63b7dSRichard Lowe size = sizeof (struct Vpath_alias); 58810d63b7dSRichard Lowe break; 58910d63b7dSRichard Lowe case long_member_name_prop: 59010d63b7dSRichard Lowe size = sizeof (struct Long_member_name); 59110d63b7dSRichard Lowe break; 59210d63b7dSRichard Lowe case macro_append_prop: 59310d63b7dSRichard Lowe size = sizeof (struct _Macro_appendix); 59410d63b7dSRichard Lowe break; 59510d63b7dSRichard Lowe case env_mem_prop: 59610d63b7dSRichard Lowe size = sizeof (struct _Env_mem); 59710d63b7dSRichard Lowe break; 59810d63b7dSRichard Lowe default: 59910d63b7dSRichard Lowe fatal_mksh(gettext("Internal error. Unknown prop type %d"), type); 60010d63b7dSRichard Lowe } 60110d63b7dSRichard Lowe for (; prop != NULL; insert = &prop->next, prop = *insert); 60210d63b7dSRichard Lowe size += PROPERTY_HEAD_SIZE; 60310d63b7dSRichard Lowe *insert = prop = (Property) getmem(size); 60410d63b7dSRichard Lowe memset((char *) prop, 0, size); 60510d63b7dSRichard Lowe prop->type = type; 60610d63b7dSRichard Lowe prop->next = NULL; 60710d63b7dSRichard Lowe return prop; 60810d63b7dSRichard Lowe } 60910d63b7dSRichard Lowe 61010d63b7dSRichard Lowe /* 61110d63b7dSRichard Lowe * maybe_append_prop(target, type) 61210d63b7dSRichard Lowe * 61310d63b7dSRichard Lowe * Append a property to the Name if none of this type exists 61410d63b7dSRichard Lowe * else return the one already there 61510d63b7dSRichard Lowe * 61610d63b7dSRichard Lowe * Return value: 61710d63b7dSRichard Lowe * A property of the requested type for the target 61810d63b7dSRichard Lowe * 61910d63b7dSRichard Lowe * Parameters: 62010d63b7dSRichard Lowe * target The target that wants a new property 62110d63b7dSRichard Lowe * type The type of property being requested 62210d63b7dSRichard Lowe * 62310d63b7dSRichard Lowe * Global variables used: 62410d63b7dSRichard Lowe */ 62510d63b7dSRichard Lowe Property 62610d63b7dSRichard Lowe maybe_append_prop(register Name target, register Property_id type) 62710d63b7dSRichard Lowe { 62810d63b7dSRichard Lowe register Property prop; 62910d63b7dSRichard Lowe 63010d63b7dSRichard Lowe if ((prop = get_prop(target->prop, type)) != NULL) { 63110d63b7dSRichard Lowe return prop; 63210d63b7dSRichard Lowe } 63310d63b7dSRichard Lowe return append_prop(target, type); 63410d63b7dSRichard Lowe } 63510d63b7dSRichard Lowe 63610d63b7dSRichard Lowe /* 63710d63b7dSRichard Lowe * get_prop(start, type) 63810d63b7dSRichard Lowe * 63910d63b7dSRichard Lowe * Scan the property list of a Name to find the next property 64010d63b7dSRichard Lowe * of a given type. 64110d63b7dSRichard Lowe * 64210d63b7dSRichard Lowe * Return value: 64310d63b7dSRichard Lowe * The first property of the type, if any left 64410d63b7dSRichard Lowe * 64510d63b7dSRichard Lowe * Parameters: 64610d63b7dSRichard Lowe * start The first property block to check for type 64710d63b7dSRichard Lowe * type The type of property block we need 64810d63b7dSRichard Lowe * 64910d63b7dSRichard Lowe * Global variables used: 65010d63b7dSRichard Lowe */ 65110d63b7dSRichard Lowe Property 65210d63b7dSRichard Lowe get_prop(register Property start, register Property_id type) 65310d63b7dSRichard Lowe { 65410d63b7dSRichard Lowe for (; start != NULL; start = start->next) { 65510d63b7dSRichard Lowe if (start->type == type) { 65610d63b7dSRichard Lowe return start; 65710d63b7dSRichard Lowe } 65810d63b7dSRichard Lowe } 65910d63b7dSRichard Lowe return NULL; 66010d63b7dSRichard Lowe } 66110d63b7dSRichard Lowe 66210d63b7dSRichard Lowe /* 66310d63b7dSRichard Lowe * append_string(from, to, length) 66410d63b7dSRichard Lowe * 66510d63b7dSRichard Lowe * Append a C string to a make string expanding it if nessecary 66610d63b7dSRichard Lowe * 66710d63b7dSRichard Lowe * Parameters: 66810d63b7dSRichard Lowe * from The source (C style) string 66910d63b7dSRichard Lowe * to The destination (make style) string 67010d63b7dSRichard Lowe * length The length of the from string 67110d63b7dSRichard Lowe * 67210d63b7dSRichard Lowe * Global variables used: 67310d63b7dSRichard Lowe */ 67410d63b7dSRichard Lowe void 67510d63b7dSRichard Lowe append_string(register wchar_t *from, register String to, register int length) 67610d63b7dSRichard Lowe { 67710d63b7dSRichard Lowe if (length == FIND_LENGTH) { 67810d63b7dSRichard Lowe length = wcslen(from); 67910d63b7dSRichard Lowe } 68010d63b7dSRichard Lowe if (to->buffer.start == NULL) { 68110d63b7dSRichard Lowe expand_string(to, 32 + length); 68210d63b7dSRichard Lowe } 68310d63b7dSRichard Lowe if (to->buffer.end - to->text.p <= length) { 68410d63b7dSRichard Lowe expand_string(to, 68510d63b7dSRichard Lowe (to->buffer.end - to->buffer.start) * 2 + 68610d63b7dSRichard Lowe length); 68710d63b7dSRichard Lowe } 68810d63b7dSRichard Lowe if (length > 0) { 68910d63b7dSRichard Lowe (void) wcsncpy(to->text.p, from, length); 69010d63b7dSRichard Lowe to->text.p += length; 69110d63b7dSRichard Lowe } 69210d63b7dSRichard Lowe *(to->text.p) = (int) nul_char; 69310d63b7dSRichard Lowe } 69410d63b7dSRichard Lowe 69510d63b7dSRichard Lowe wchar_t * get_wstring(char *from) { 69610d63b7dSRichard Lowe if(from == NULL) { 69710d63b7dSRichard Lowe return NULL; 69810d63b7dSRichard Lowe } 69910d63b7dSRichard Lowe getwstring_count++; 70010d63b7dSRichard Lowe wchar_t * wcbuf = ALLOC_WC(strlen(from) + 1); 70110d63b7dSRichard Lowe mbstowcs(wcbuf, from, strlen(from)+1); 70210d63b7dSRichard Lowe return wcbuf; 70310d63b7dSRichard Lowe } 70410d63b7dSRichard Lowe 70510d63b7dSRichard Lowe void 70610d63b7dSRichard Lowe append_string(register char *from, register String to, register int length) 70710d63b7dSRichard Lowe { 70810d63b7dSRichard Lowe if (length == FIND_LENGTH) { 70910d63b7dSRichard Lowe length = strlen(from); 71010d63b7dSRichard Lowe } 71110d63b7dSRichard Lowe if (to->buffer.start == NULL) { 71210d63b7dSRichard Lowe expand_string(to, 32 + length); 71310d63b7dSRichard Lowe } 71410d63b7dSRichard Lowe if (to->buffer.end - to->text.p <= length) { 71510d63b7dSRichard Lowe expand_string(to, 71610d63b7dSRichard Lowe (to->buffer.end - to->buffer.start) * 2 + 71710d63b7dSRichard Lowe length); 71810d63b7dSRichard Lowe } 71910d63b7dSRichard Lowe if (length > 0) { 72010d63b7dSRichard Lowe (void) mbstowcs(to->text.p, from, length); 72110d63b7dSRichard Lowe to->text.p += length; 72210d63b7dSRichard Lowe } 72310d63b7dSRichard Lowe *(to->text.p) = (int) nul_char; 72410d63b7dSRichard Lowe } 72510d63b7dSRichard Lowe 72610d63b7dSRichard Lowe /* 72710d63b7dSRichard Lowe * expand_string(string, length) 72810d63b7dSRichard Lowe * 72910d63b7dSRichard Lowe * Allocate more memory for strings that run out of space. 73010d63b7dSRichard Lowe * 73110d63b7dSRichard Lowe * Parameters: 73210d63b7dSRichard Lowe * string The make style string we want to expand 73310d63b7dSRichard Lowe * length The new length we need 73410d63b7dSRichard Lowe * 73510d63b7dSRichard Lowe * Global variables used: 73610d63b7dSRichard Lowe */ 73710d63b7dSRichard Lowe static void 73810d63b7dSRichard Lowe expand_string(register String string, register int length) 73910d63b7dSRichard Lowe { 74010d63b7dSRichard Lowe register wchar_t *p; 74110d63b7dSRichard Lowe 74210d63b7dSRichard Lowe if (string->buffer.start == NULL) { 74310d63b7dSRichard Lowe /* For strings that have no memory allocated */ 74410d63b7dSRichard Lowe string->buffer.start = 74510d63b7dSRichard Lowe string->text.p = 74610d63b7dSRichard Lowe string->text.end = 74710d63b7dSRichard Lowe ALLOC_WC(length); 74810d63b7dSRichard Lowe string->buffer.end = string->buffer.start + length; 74910d63b7dSRichard Lowe string->text.p[0] = (int) nul_char; 75010d63b7dSRichard Lowe string->free_after_use = true; 75110d63b7dSRichard Lowe expandstring_count++; 75210d63b7dSRichard Lowe return; 75310d63b7dSRichard Lowe } 75410d63b7dSRichard Lowe if (string->buffer.end - string->buffer.start >= length) { 75510d63b7dSRichard Lowe /* If we really don't need more memory. */ 75610d63b7dSRichard Lowe return; 75710d63b7dSRichard Lowe } 75810d63b7dSRichard Lowe /* 75910d63b7dSRichard Lowe * Get more memory, copy the string and free the old buffer if 76010d63b7dSRichard Lowe * it is was malloc()'ed. 76110d63b7dSRichard Lowe */ 76210d63b7dSRichard Lowe expandstring_count++; 76310d63b7dSRichard Lowe p = ALLOC_WC(length); 76410d63b7dSRichard Lowe (void) wcscpy(p, string->buffer.start); 76510d63b7dSRichard Lowe string->text.p = p + (string->text.p - string->buffer.start); 76610d63b7dSRichard Lowe string->text.end = p + (string->text.end - string->buffer.start); 76710d63b7dSRichard Lowe string->buffer.end = p + length; 76810d63b7dSRichard Lowe if (string->free_after_use) { 76910d63b7dSRichard Lowe retmem(string->buffer.start); 77010d63b7dSRichard Lowe } 77110d63b7dSRichard Lowe string->buffer.start = p; 77210d63b7dSRichard Lowe string->free_after_use = true; 77310d63b7dSRichard Lowe } 77410d63b7dSRichard Lowe 77510d63b7dSRichard Lowe /* 77610d63b7dSRichard Lowe * append_char(from, to) 77710d63b7dSRichard Lowe * 77810d63b7dSRichard Lowe * Append one char to a make string expanding it if nessecary 77910d63b7dSRichard Lowe * 78010d63b7dSRichard Lowe * Parameters: 78110d63b7dSRichard Lowe * from Single character to append to string 78210d63b7dSRichard Lowe * to The destination (make style) string 78310d63b7dSRichard Lowe * 78410d63b7dSRichard Lowe * Global variables used: 78510d63b7dSRichard Lowe */ 78610d63b7dSRichard Lowe void 78710d63b7dSRichard Lowe append_char(wchar_t from, register String to) 78810d63b7dSRichard Lowe { 78910d63b7dSRichard Lowe if (to->buffer.start == NULL) { 79010d63b7dSRichard Lowe expand_string(to, 32); 79110d63b7dSRichard Lowe } 79210d63b7dSRichard Lowe if (to->buffer.end - to->text.p <= 2) { 79310d63b7dSRichard Lowe expand_string(to, to->buffer.end - to->buffer.start + 32); 79410d63b7dSRichard Lowe } 79510d63b7dSRichard Lowe *(to->text.p)++ = from; 79610d63b7dSRichard Lowe *(to->text.p) = (int) nul_char; 79710d63b7dSRichard Lowe } 79810d63b7dSRichard Lowe 79910d63b7dSRichard Lowe /* 80010d63b7dSRichard Lowe * handle_interrupt_mksh() 80110d63b7dSRichard Lowe * 80210d63b7dSRichard Lowe * This is where C-C traps are caught. 80310d63b7dSRichard Lowe */ 80410d63b7dSRichard Lowe void 80510d63b7dSRichard Lowe handle_interrupt_mksh(int) 80610d63b7dSRichard Lowe { 80710d63b7dSRichard Lowe (void) fflush(stdout); 80810d63b7dSRichard Lowe /* Make sure the processes running under us terminate first. */ 80910d63b7dSRichard Lowe if (childPid > 0) { 81010d63b7dSRichard Lowe kill(childPid, SIGTERM); 81110d63b7dSRichard Lowe childPid = -1; 81210d63b7dSRichard Lowe } 81310d63b7dSRichard Lowe while (wait((int *) NULL) != -1); 81410d63b7dSRichard Lowe exit_status = 2; 81510d63b7dSRichard Lowe exit(2); 81610d63b7dSRichard Lowe } 81710d63b7dSRichard Lowe 81810d63b7dSRichard Lowe /* 81910d63b7dSRichard Lowe * setup_interrupt() 82010d63b7dSRichard Lowe * 82110d63b7dSRichard Lowe * This routine saves the original interrupt handler pointers 82210d63b7dSRichard Lowe * 82310d63b7dSRichard Lowe * Parameters: 82410d63b7dSRichard Lowe * 82510d63b7dSRichard Lowe * Static variables used: 82610d63b7dSRichard Lowe * sigivalue The original signal handler 82710d63b7dSRichard Lowe * sigqvalue The original signal handler 82810d63b7dSRichard Lowe * sigtvalue The original signal handler 82910d63b7dSRichard Lowe * sighvalue The original signal handler 83010d63b7dSRichard Lowe */ 83110d63b7dSRichard Lowe void 83210d63b7dSRichard Lowe setup_interrupt(register void (*handler) (int)) 83310d63b7dSRichard Lowe { 83410d63b7dSRichard Lowe sigivalue = bsd_signal(SIGINT, SIG_IGN); 83510d63b7dSRichard Lowe sigqvalue = bsd_signal(SIGQUIT, SIG_IGN); 83610d63b7dSRichard Lowe sigtvalue = bsd_signal(SIGTERM, SIG_IGN); 83710d63b7dSRichard Lowe sighvalue = bsd_signal(SIGHUP, SIG_IGN); 83810d63b7dSRichard Lowe enable_interrupt(handler); 83910d63b7dSRichard Lowe } 84010d63b7dSRichard Lowe 84110d63b7dSRichard Lowe 84210d63b7dSRichard Lowe void 84310d63b7dSRichard Lowe mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n) 84410d63b7dSRichard Lowe { 84510d63b7dSRichard Lowe if(mbstowcs(pwcs, s, n) == -1) { 84610d63b7dSRichard Lowe fatal_mksh(gettext("The string `%s' is not valid in current locale"), s); 84710d63b7dSRichard Lowe } 84810d63b7dSRichard Lowe } 84910d63b7dSRichard Lowe 85010d63b7dSRichard Lowe 85110d63b7dSRichard Lowe 85210d63b7dSRichard Lowe Wstring::Wstring() 85310d63b7dSRichard Lowe { 85410d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf); 85510d63b7dSRichard Lowe } 85610d63b7dSRichard Lowe 85710d63b7dSRichard Lowe Wstring::Wstring(struct _Name * name) 85810d63b7dSRichard Lowe { 85910d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf); 86010d63b7dSRichard Lowe append_string(name->string_mb, &string, name->hash.length); 86110d63b7dSRichard Lowe } 86210d63b7dSRichard Lowe 86310d63b7dSRichard Lowe Wstring::~Wstring() 86410d63b7dSRichard Lowe { 86510d63b7dSRichard Lowe if(string.free_after_use) { 86610d63b7dSRichard Lowe retmem(string.buffer.start); 86710d63b7dSRichard Lowe } 86810d63b7dSRichard Lowe } 86910d63b7dSRichard Lowe 87010d63b7dSRichard Lowe void 87110d63b7dSRichard Lowe Wstring::init(struct _Name * name) 87210d63b7dSRichard Lowe { 87310d63b7dSRichard Lowe if(string.free_after_use) { 87410d63b7dSRichard Lowe retmem(string.buffer.start); 87510d63b7dSRichard Lowe } 87610d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf); 87710d63b7dSRichard Lowe append_string(name->string_mb, &string, name->hash.length); 87810d63b7dSRichard Lowe } 87910d63b7dSRichard Lowe 88010d63b7dSRichard Lowe void 88110d63b7dSRichard Lowe Wstring::init(wchar_t * name, unsigned length) 88210d63b7dSRichard Lowe { 88310d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, string_buf); 88410d63b7dSRichard Lowe append_string(name, &string, length); 88510d63b7dSRichard Lowe string.buffer.start[length] = 0; 88610d63b7dSRichard Lowe } 88710d63b7dSRichard Lowe 88810d63b7dSRichard Lowe Boolean 88910d63b7dSRichard Lowe Wstring::equaln(wchar_t * str, unsigned length) 89010d63b7dSRichard Lowe { 89110d63b7dSRichard Lowe return (Boolean)IS_WEQUALN(string.buffer.start, str, length); 89210d63b7dSRichard Lowe } 89310d63b7dSRichard Lowe 89410d63b7dSRichard Lowe Boolean 89510d63b7dSRichard Lowe Wstring::equaln(Wstring * str, unsigned length) 89610d63b7dSRichard Lowe { 89710d63b7dSRichard Lowe return (Boolean)IS_WEQUALN(string.buffer.start, str->string.buffer.start, length); 89810d63b7dSRichard Lowe } 89910d63b7dSRichard Lowe 90010d63b7dSRichard Lowe Boolean 90110d63b7dSRichard Lowe Wstring::equal(wchar_t * str, unsigned off, unsigned length) 90210d63b7dSRichard Lowe { 90310d63b7dSRichard Lowe return (Boolean)IS_WEQUALN(string.buffer.start + off, str, length); 90410d63b7dSRichard Lowe } 90510d63b7dSRichard Lowe 90610d63b7dSRichard Lowe Boolean 90710d63b7dSRichard Lowe Wstring::equal(wchar_t * str, unsigned off) 90810d63b7dSRichard Lowe { 90910d63b7dSRichard Lowe return (Boolean)IS_WEQUAL(string.buffer.start + off, str); 91010d63b7dSRichard Lowe } 91110d63b7dSRichard Lowe 91210d63b7dSRichard Lowe Boolean 91310d63b7dSRichard Lowe Wstring::equal(wchar_t * str) 91410d63b7dSRichard Lowe { 91510d63b7dSRichard Lowe return equal(str, 0); 91610d63b7dSRichard Lowe } 91710d63b7dSRichard Lowe 91810d63b7dSRichard Lowe Boolean 91910d63b7dSRichard Lowe Wstring::equal(Wstring * str, unsigned off, unsigned length) 92010d63b7dSRichard Lowe { 92110d63b7dSRichard Lowe return (Boolean)IS_WEQUALN(string.buffer.start + off, str->string.buffer.start, length); 92210d63b7dSRichard Lowe } 92310d63b7dSRichard Lowe 92410d63b7dSRichard Lowe Boolean 92510d63b7dSRichard Lowe Wstring::equal(Wstring * str) 92610d63b7dSRichard Lowe { 92710d63b7dSRichard Lowe return equal(str, 0); 92810d63b7dSRichard Lowe } 92910d63b7dSRichard Lowe 93010d63b7dSRichard Lowe Boolean 93110d63b7dSRichard Lowe Wstring::equal(Wstring * str, unsigned off) 93210d63b7dSRichard Lowe { 93310d63b7dSRichard Lowe return (Boolean)IS_WEQUAL(string.buffer.start + off, str->string.buffer.start); 93410d63b7dSRichard Lowe } 93510d63b7dSRichard Lowe 93610d63b7dSRichard Lowe void 93710d63b7dSRichard Lowe Wstring::append_to_str(struct _String * str, unsigned off, unsigned length) 93810d63b7dSRichard Lowe { 93910d63b7dSRichard Lowe append_string(string.buffer.start + off, str, length); 94010d63b7dSRichard Lowe } 94110d63b7dSRichard Lowe 94210d63b7dSRichard Lowe Name 94310d63b7dSRichard Lowe Name_set::lookup(const char *key) 94410d63b7dSRichard Lowe { 94510d63b7dSRichard Lowe for (entry *node = root; node != 0;) { 94610d63b7dSRichard Lowe int res = strcmp(key, node->name->string_mb); 94710d63b7dSRichard Lowe if (res < 0) { 94810d63b7dSRichard Lowe node = node->left; 94910d63b7dSRichard Lowe } else if (res > 0) { 95010d63b7dSRichard Lowe node = node->right; 95110d63b7dSRichard Lowe } else { 95210d63b7dSRichard Lowe return node->name; 95310d63b7dSRichard Lowe } 95410d63b7dSRichard Lowe } 95510d63b7dSRichard Lowe return 0; 95610d63b7dSRichard Lowe } 95710d63b7dSRichard Lowe 95810d63b7dSRichard Lowe Name 95910d63b7dSRichard Lowe Name_set::insert(const char *key, Boolean &found) 96010d63b7dSRichard Lowe { 96110d63b7dSRichard Lowe Name name = 0; 96210d63b7dSRichard Lowe 96310d63b7dSRichard Lowe if (root != 0) { 96410d63b7dSRichard Lowe for (entry *node = root; name == 0;) { 96510d63b7dSRichard Lowe int res = strcmp(key, node->name->string_mb); 96610d63b7dSRichard Lowe if (res < 0) { 96710d63b7dSRichard Lowe if (node->left != 0) { 96810d63b7dSRichard Lowe node = node->left; 96910d63b7dSRichard Lowe } else { 97010d63b7dSRichard Lowe found = false; 97110d63b7dSRichard Lowe name = ALLOC(Name); 97210d63b7dSRichard Lowe 97310d63b7dSRichard Lowe node->left = new entry(name, node); 97410d63b7dSRichard Lowe rebalance(node); 97510d63b7dSRichard Lowe } 97610d63b7dSRichard Lowe } else if (res > 0) { 97710d63b7dSRichard Lowe if (node->right != 0) { 97810d63b7dSRichard Lowe node = node->right; 97910d63b7dSRichard Lowe } else { 98010d63b7dSRichard Lowe found = false; 98110d63b7dSRichard Lowe name = ALLOC(Name); 98210d63b7dSRichard Lowe 98310d63b7dSRichard Lowe node->right = new entry(name, node); 98410d63b7dSRichard Lowe rebalance(node); 98510d63b7dSRichard Lowe } 98610d63b7dSRichard Lowe } else { 98710d63b7dSRichard Lowe found = true; 98810d63b7dSRichard Lowe name = node->name; 98910d63b7dSRichard Lowe } 99010d63b7dSRichard Lowe } 99110d63b7dSRichard Lowe } else { 99210d63b7dSRichard Lowe found = false; 99310d63b7dSRichard Lowe name = ALLOC(Name); 99410d63b7dSRichard Lowe 99510d63b7dSRichard Lowe root = new entry(name, 0); 99610d63b7dSRichard Lowe } 99710d63b7dSRichard Lowe return name; 99810d63b7dSRichard Lowe } 99910d63b7dSRichard Lowe 100010d63b7dSRichard Lowe void 100110d63b7dSRichard Lowe Name_set::insert(Name name) { 100210d63b7dSRichard Lowe if (root != 0) { 100310d63b7dSRichard Lowe for (entry *node = root;;) { 100410d63b7dSRichard Lowe int res = strcmp(name->string_mb, node->name->string_mb); 100510d63b7dSRichard Lowe if (res < 0) { 100610d63b7dSRichard Lowe if (node->left != 0) { 100710d63b7dSRichard Lowe node = node->left; 100810d63b7dSRichard Lowe } else { 100910d63b7dSRichard Lowe node->left = new entry(name, node); 101010d63b7dSRichard Lowe rebalance(node); 101110d63b7dSRichard Lowe break; 101210d63b7dSRichard Lowe } 101310d63b7dSRichard Lowe } else if (res > 0) { 101410d63b7dSRichard Lowe if (node->right != 0) { 101510d63b7dSRichard Lowe node = node->right; 101610d63b7dSRichard Lowe } else { 101710d63b7dSRichard Lowe node->right = new entry(name, node); 101810d63b7dSRichard Lowe rebalance(node); 101910d63b7dSRichard Lowe break; 102010d63b7dSRichard Lowe } 102110d63b7dSRichard Lowe } else { 102210d63b7dSRichard Lowe // should be an error: inserting already existing name 102310d63b7dSRichard Lowe break; 102410d63b7dSRichard Lowe } 102510d63b7dSRichard Lowe } 102610d63b7dSRichard Lowe } else { 102710d63b7dSRichard Lowe root = new entry(name, 0); 102810d63b7dSRichard Lowe } 102910d63b7dSRichard Lowe } 103010d63b7dSRichard Lowe 103110d63b7dSRichard Lowe void 103210d63b7dSRichard Lowe Name_set::rebalance(Name_set::entry *node) { 103310d63b7dSRichard Lowe for (; node != 0; node = node->parent) { 103410d63b7dSRichard Lowe entry *right = node->right; 103510d63b7dSRichard Lowe entry *left = node->left; 103610d63b7dSRichard Lowe 103710d63b7dSRichard Lowe unsigned rdepth = (right != 0) ? right->depth : 0; 103810d63b7dSRichard Lowe unsigned ldepth = (left != 0) ? left->depth : 0; 103910d63b7dSRichard Lowe 104010d63b7dSRichard Lowe if (ldepth > rdepth + 1) { 104110d63b7dSRichard Lowe if ((node->left = left->right) != 0) { 104210d63b7dSRichard Lowe left->right->parent = node; 104310d63b7dSRichard Lowe } 104410d63b7dSRichard Lowe if ((left->parent = node->parent) != 0) { 104510d63b7dSRichard Lowe if (node == node->parent->right) { 104610d63b7dSRichard Lowe node->parent->right = left; 104710d63b7dSRichard Lowe } else { 104810d63b7dSRichard Lowe node->parent->left = left; 104910d63b7dSRichard Lowe } 105010d63b7dSRichard Lowe } else { 105110d63b7dSRichard Lowe root = left; 105210d63b7dSRichard Lowe } 105310d63b7dSRichard Lowe left->right = node; 105410d63b7dSRichard Lowe node->parent = left; 105510d63b7dSRichard Lowe 105610d63b7dSRichard Lowe node->setup_depth(); 105710d63b7dSRichard Lowe node = left; 105810d63b7dSRichard Lowe } else if (rdepth > ldepth + 1) { 105910d63b7dSRichard Lowe if ((node->right = right->left) != 0) { 106010d63b7dSRichard Lowe right->left->parent = node; 106110d63b7dSRichard Lowe } 106210d63b7dSRichard Lowe if ((right->parent = node->parent) != 0) { 106310d63b7dSRichard Lowe if (node == node->parent->right) { 106410d63b7dSRichard Lowe node->parent->right = right; 106510d63b7dSRichard Lowe } else { 106610d63b7dSRichard Lowe node->parent->left = right; 106710d63b7dSRichard Lowe } 106810d63b7dSRichard Lowe } else { 106910d63b7dSRichard Lowe root = right; 107010d63b7dSRichard Lowe } 107110d63b7dSRichard Lowe right->left = node; 107210d63b7dSRichard Lowe node->parent = right; 107310d63b7dSRichard Lowe 107410d63b7dSRichard Lowe node->setup_depth(); 107510d63b7dSRichard Lowe node = right; 107610d63b7dSRichard Lowe } 107710d63b7dSRichard Lowe node->setup_depth(); 107810d63b7dSRichard Lowe } 107910d63b7dSRichard Lowe } 108010d63b7dSRichard Lowe 108110d63b7dSRichard Lowe Name_set::iterator 108210d63b7dSRichard Lowe Name_set::begin() const { 108310d63b7dSRichard Lowe for (entry *node = root; node != 0; node = node->left) { 108410d63b7dSRichard Lowe if (node->left == 0) { 108510d63b7dSRichard Lowe return iterator(node); 108610d63b7dSRichard Lowe } 108710d63b7dSRichard Lowe } 108810d63b7dSRichard Lowe return iterator(); 108910d63b7dSRichard Lowe } 109010d63b7dSRichard Lowe 109110d63b7dSRichard Lowe Name_set::iterator& 109210d63b7dSRichard Lowe Name_set::iterator::operator++() { 109310d63b7dSRichard Lowe if (node != 0) { 109410d63b7dSRichard Lowe if (node->right != 0) { 109510d63b7dSRichard Lowe node = node->right; 109610d63b7dSRichard Lowe while (node->left != 0) { 109710d63b7dSRichard Lowe node = node->left; 109810d63b7dSRichard Lowe } 109910d63b7dSRichard Lowe } else { 110010d63b7dSRichard Lowe while ((node->parent != 0) && (node->parent->right == node)) { 110110d63b7dSRichard Lowe node = node->parent; 110210d63b7dSRichard Lowe } 110310d63b7dSRichard Lowe node = node->parent; 110410d63b7dSRichard Lowe } 110510d63b7dSRichard Lowe } 110610d63b7dSRichard Lowe return *this; 110710d63b7dSRichard Lowe } 1108