1/*$Header: /p/tcsh/cvsroot/tcsh/win32/support.c,v 1.14 2008/08/31 14:09:01 amold Exp $*/ 2/*- 3 * Copyright (c) 1980, 1991 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the University nor the names of its contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31/* 32 * support.c 33 * various routines to do exec, etc. 34 * 35 */ 36 37#define WIN32_LEAN_AND_MEAN 38#include <windows.h> 39#include <wincon.h> 40#include <fcntl.h> 41#include <errno.h> 42#include <stdio.h> 43#include <locale.h> 44#include "ntport.h" 45#include "sh.err.h" 46#include "sh.h" 47#include "nt.const.h" 48 49 50DWORD gdwPlatform,gdwVersion; 51unsigned short __nt_really_exec = 0,__nt_child_nohupped =0; 52DWORD gdwStackSize = 524288;//0.5 MB 53 54void path_slashify(char *pstr) { 55 while(*pstr) { 56#ifdef DSPMBYTE 57 if (Ismbyte1(*pstr) && *(pstr + 1)) 58 pstr ++; 59 else 60#endif /* DSPMBYTE */ 61 if (*pstr == '\\') 62 *pstr = '/'; 63 pstr++; 64 } 65} 66 67void do_nothing(const wchar_t *p1, const wchar_t *p2, const wchar_t*p3, 68 unsigned int p4, uintptr_t p5) { 69 UNREFERENCED_PARAMETER(p1); 70 UNREFERENCED_PARAMETER(p2); 71 UNREFERENCED_PARAMETER(p3); 72 UNREFERENCED_PARAMETER(p4); 73 UNREFERENCED_PARAMETER(p5); 74} 75void nt_init(void) { 76 77 78#ifdef SECURE_CD 79 { 80 char temp[512];/*FIXBUF*/ 81 extern char gcurr_drive; 82 if(!GetCurrentDirectory(512,temp)) 83 ExitProcess((DWORD)-1); 84 gcurr_drive=temp[0]; 85 } 86#endif SECURE_CD 87 88 _set_invalid_parameter_handler(do_nothing); 89 init_stdio(); 90 nt_init_signals(); 91 nt_term_init(); 92 init_hb_subst(); 93 setlocale(LC_ALL,""); 94 init_shell_dll(); 95 init_plister(); 96 fork_init(); 97 init_clipboard(); 98 return; 99} 100void nt_cleanup(void){ 101 nt_term_cleanup(); 102 nt_cleanup_signals(); 103 cleanup_netbios(); 104} 105void caseify_pwd(char *curwd) { 106 char *sp, *dp, p,*s; 107 WIN32_FIND_DATA fdata; 108 HANDLE hFind; 109 110 if (gdwPlatform !=VER_PLATFORM_WIN32_NT) 111 return; 112 113 if (*curwd == '\\' && (!curwd[1] || curwd[1] == '\\')) 114 return; 115 sp = curwd +3; 116 dp = curwd +3; 117 do { 118 p= *sp; 119 if (p && p != '\\'){ 120 sp++; 121 continue; 122 } 123 else { 124 *sp = 0; 125 hFind = FindFirstFile(curwd,&fdata); 126 *sp = p; 127 if (hFind != INVALID_HANDLE_VALUE) { 128 FindClose(hFind); 129 s = fdata.cFileName; 130 while(*s) { 131 *dp++ = *s++; 132 } 133 dp++; 134 sp = dp; 135 } 136 else { 137 sp++; 138 dp = sp; 139 } 140 } 141 sp++; 142 }while(p != 0); 143 144} 145static char defcwd[MAX_PATH]; 146char * forward_slash_get_cwd(char * path, size_t maxlen) { 147 148 char *ptemp; 149 Char *vp; 150 int rc ; 151 152 if ((path == NULL) || (maxlen == 0)) { 153 path = &defcwd[0]; 154 maxlen = MAX_PATH; 155 } 156 157 rc = GetCurrentDirectory((DWORD)maxlen,path); 158 if (rc > maxlen) { 159 errno = ERANGE; 160 return NULL; 161 } 162 vp = varval(STRNTcaseifypwd); 163 if (vp != STRNULL) { 164 caseify_pwd(path); 165 } 166 ptemp=path; 167 168 path_slashify(ptemp); 169 170 return path; 171} 172void getmachine (void) { 173 174 char temp[256]; 175 char *vendor, *ostype; 176 OSVERSIONINFO osver; 177 SYSTEM_INFO sysinfo; 178 179 180 memset(&osver,0,sizeof(osver)); 181 memset(&sysinfo,0,sizeof(sysinfo)); 182 vendor = "Microsoft"; 183 184 tsetenv(STRVENDOR,str2short(vendor)); 185 186 osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 187 188 if (!GetVersionEx(&osver)) { 189 MessageBox(NULL,"GetVersionEx failed in getmachine", 190 "tcsh",MB_ICONHAND); 191 ExitProcess(0xFF); 192 } 193 GetSystemInfo(&sysinfo); 194 195 if(osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { 196 char *ostr; 197 ostype = "WindowsNT"; 198 ostr = "Windows NT"; 199 200 (void)StringCbPrintf(temp,sizeof(temp),"%s %d.%d Build %d (%s)", 201 ostr, 202 osver.dwMajorVersion,osver.dwMinorVersion, 203 osver.dwBuildNumber, 204 osver.szCSDVersion[0]?osver.szCSDVersion:""); 205 tsetenv(STRHOSTTYPE,str2short(temp)); 206 } 207 else if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { 208 ostype = "Windows9x"; 209 (void)StringCbPrintf(temp,sizeof(temp), 210 "Win9x %d.%d:%d",osver.dwMajorVersion,osver.dwMinorVersion, 211 LOWORD(osver.dwBuildNumber)); 212 tsetenv(STRHOSTTYPE,str2short(temp)); 213 } 214 else { 215 ostype = "WindowsWhoKnows"; 216 MessageBox(NULL,"Unknown platform","tcsh",MB_ICONHAND); 217 } 218 tsetenv(STROSTYPE,str2short(ostype)); 219 switch (sysinfo.wProcessorArchitecture) { 220 case PROCESSOR_ARCHITECTURE_INTEL: 221 if ( ( sysinfo.wProcessorLevel < 3) || 222 ( sysinfo.wProcessorLevel > 9) ) 223 sysinfo.wProcessorLevel = 3; 224 225 (void)StringCbPrintf(temp,sizeof(temp), 226 "i%d86",sysinfo.wProcessorLevel); 227 break; 228 case PROCESSOR_ARCHITECTURE_ALPHA: 229 (void)StringCbPrintf(temp,sizeof(temp),"Alpha"); 230 break; 231 case PROCESSOR_ARCHITECTURE_MIPS: 232 (void)StringCbPrintf(temp,sizeof(temp),"Mips"); 233 break; 234 case PROCESSOR_ARCHITECTURE_PPC: 235 (void)StringCbPrintf(temp,sizeof(temp),"PPC"); 236 break; 237 case PROCESSOR_ARCHITECTURE_AMD64: 238 (void)StringCbPrintf(temp,sizeof(temp),"AMD64"); 239 break; 240 default: 241 (void)StringCbPrintf(temp,sizeof(temp),"Unknown"); 242 break; 243 } 244 tsetenv(STRMACHTYPE,str2short(temp)); 245 246} 247void nt_exec(char *prog, char**args) { 248 nt_execve(prog,args,NULL); 249} 250void nt_execve(char *prog, char**args, char**envir ) { 251 252 STARTUPINFO si; 253 PROCESS_INFORMATION pi; 254 HANDLE htemp; 255 BOOL bRet; 256 DWORD type=0; 257 DWORD dwCreationflags; 258 unsigned int priority; 259 char *argv0= NULL; 260 char *cmdstr, *cmdend ; 261 char *originalPtr; 262 unsigned int cmdsize,cmdlen; 263 char *p2; 264 char **savedargs; 265 int retries=0; 266 int hasdot =0; 267 int is_winnt ; 268 269 UNREFERENCED_PARAMETER(envir); 270 271 memset(&si,0,sizeof(si)); 272 savedargs = args; 273 274 /* 275 * This memory is not freed because we are exec()ed and will 276 * not be alive long. 277 */ 278 originalPtr = cmdstr= heap_alloc(MAX_PATH<<2); 279 280 is_winnt = (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS); 281 282 283 cmdsize = MAX_PATH<<2; 284 285 p2 = cmdstr; 286 287 cmdlen = 0; 288 cmdlen += copy_quote_and_fix_slashes(prog,cmdstr,&hasdot); 289 290 p2 += cmdlen; 291 292 /* If the command was not quoted , 293 skip initial character we left for quote */ 294 if (*cmdstr != '"') { 295 *cmdstr = 'A'; 296 cmdstr++; 297 cmdsize--; 298 } 299 *p2 = 0; 300 cmdend = p2; 301 302 303 if (!is_winnt){ 304 argv0 = NULL; 305 goto win95_directly_here; 306 } 307 else { 308 argv0 = heap_alloc(MAX_PATH); /* not freed */ 309 (void)StringCbPrintf(argv0,MAX_PATH,"%s",prog); 310 } 311 312retry: 313 314 bRet=GetBinaryType(argv0,&type); 315 dprintf("binary type for %s is %d\n",argv0,bRet); 316 // 317 // For NT, append .EXE and retry 318 // 319 if (is_winnt && !bRet ) { 320 /* Don't append .EXE if it could be a script file */ 321 if (GetLastError() == ERROR_BAD_EXE_FORMAT){ 322 errno = ENOEXEC; 323 if (!__nt_only_start_exes) 324 try_shell_ex(args,1,FALSE); //can't throw on error 325 return; 326 } 327 else if ( retries ){ 328 if ( 329 ( (argv0[0] == '\\') ||(argv0[0] == '/') ) && 330 ( (argv0[1] == '\\') ||(argv0[1] == '/') ) && 331 (!args[1]) 332 ) 333 if (!__nt_only_start_exes) 334 try_shell_ex(args,1,FALSE); 335 errno = ENOENT; 336 } 337 if (retries > 1){ 338 return; 339 } 340 // Try uppercase once and then lower case 341 // 342 if (!retries) { 343 (void)StringCbPrintf(argv0,MAX_PATH,"%s.exe",prog); 344 } 345 else { 346 (void)StringCbPrintf(argv0,MAX_PATH,"%s.EXE",prog); 347 /* fix for clearcase */ 348 } 349 retries++; 350 goto retry; 351 } 352 353win95_directly_here: 354 355 si.cb = sizeof(STARTUPINFO); 356 si.dwFlags = STARTF_USESTDHANDLES; 357 htemp= (HANDLE)_get_osfhandle(0); 358 DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(), 359 &si.hStdInput,0,TRUE,DUPLICATE_SAME_ACCESS); 360 htemp= (HANDLE)_get_osfhandle(1); 361 DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(), 362 &si.hStdOutput,0,TRUE,DUPLICATE_SAME_ACCESS); 363 htemp= (HANDLE)_get_osfhandle(2); 364 DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(), 365 &si.hStdError,0,TRUE,DUPLICATE_SAME_ACCESS); 366 367 368 369 args++; // the first arg is the command 370 371 372 dprintf("nt_execve calling c_a_a_q"); 373 if(!concat_args_and_quote(args,&originalPtr,&cmdstr,&cmdlen,&cmdend, 374 &cmdsize)) 375 { 376 dprintf("concat_args_and_quote failed\n"); 377 heap_free(originalPtr); 378 errno = ENOMEM; 379 goto fail_return; 380 } 381 382 *cmdend = 0; 383 384 dwCreationflags = GetPriorityClass(GetCurrentProcess()); 385 if (__nt_child_nohupped) { 386 dwCreationflags |= DETACHED_PROCESS; 387 } 388 priority = GetThreadPriority(GetCurrentThread()); 389 390 (void)fix_path_for_child(); 391 392 if (is_winnt) 393 dwCreationflags |= CREATE_SUSPENDED; 394 395 396re_cp: 397 dprintf("argv0 %s cmdstr %s\n",argv0,cmdstr); 398 bRet = CreateProcessA(argv0, cmdstr, 399 NULL, NULL, 400 TRUE, // need this for redirecting std handles 401 dwCreationflags, 402 NULL, NULL, 403 &si, 404 &pi); 405 if (!bRet){ 406 if (GetLastError() == ERROR_BAD_EXE_FORMAT) { 407 if (!__nt_only_start_exes) 408 try_shell_ex(savedargs,1,FALSE); 409 errno = ENOEXEC; 410 } 411 else if (GetLastError() == ERROR_INVALID_PARAMETER) { 412 /* can't get invalid parameter, so this must be 413 * the case when we exceed the command length limit. 414 */ 415 errno = ENAMETOOLONG; 416 } 417 else { 418 errno = ENOENT; 419 } 420 if (!is_winnt && !hasdot) { //append '.' to the end if needed 421 (void)StringCbCat(cmdstr,cmdsize,"."); 422 hasdot=1; 423 goto re_cp; 424 } 425 } 426 else{ 427 int gui_app ; 428 char guivar[50]; 429 430 if (GetEnvironmentVariable("TCSH_NOASYNCGUI",guivar,50)) 431 gui_app=0; 432 else { 433 if (is_winnt || hasdot) 434 gui_app= is_gui(argv0); 435 else 436 gui_app = is_9x_gui(prog); 437 } 438 439 if (is_winnt && !SetThreadPriority(pi.hThread,priority) ) { 440 priority =GetLastError(); 441 } 442 if (is_winnt) 443 ResumeThread(pi.hThread); 444 errno= 0; 445 446 if (__nt_really_exec||__nt_child_nohupped || gui_app){ 447 ExitProcess(0); 448 } 449 else { 450 DWORD exitcode=0; 451 WaitForSingleObject(pi.hProcess,INFINITE); 452 (void)GetExitCodeProcess(pi.hProcess,&exitcode); 453 CloseHandle(pi.hProcess); 454 CloseHandle(pi.hThread); 455 /* 456 * If output was redirected to /dev/clipboard, 457 * we need to close the pipe handles 458 */ 459 if (is_dev_clipboard_active) { 460 CloseHandle((HANDLE)_get_osfhandle(0)); 461 CloseHandle((HANDLE)_get_osfhandle(1)); 462 CloseHandle((HANDLE)_get_osfhandle(2)); 463 CloseHandle(si.hStdInput); 464 CloseHandle(si.hStdOutput); 465 CloseHandle(si.hStdError); 466 WaitForSingleObject(ghdevclipthread,60*1000); 467 } 468 ExitProcess(exitcode); 469 } 470 } 471fail_return: 472 CloseHandle(si.hStdInput); 473 CloseHandle(si.hStdOutput); 474 CloseHandle(si.hStdError); 475 return; 476} 477/* This function from Mark Tucker (mtucker@fiji.sidefx.com) */ 478int quoteProtect(char *dest, char *src,unsigned long destsize) { 479 char *prev, *curr; 480 for (curr = src; *curr; curr++) { 481 482 // Protect " from MS-DOS expansion 483 if (*curr == '"') { 484 // Now, protect each preceeding backslash 485 for (prev = curr-1; prev >= src && *prev == '\\'; prev--) { 486 *dest++ = '\\'; 487 destsize--; 488 if(destsize == 0) 489 return ERROR_BUFFER_OVERFLOW; 490 } 491 492 *dest++ = '\\'; 493 destsize--; 494 if(destsize == 0) 495 return ERROR_BUFFER_OVERFLOW; 496 } 497 *dest++ = *curr; 498 destsize--; 499 if(destsize == 0) 500 return ERROR_BUFFER_OVERFLOW; 501 502 } 503 *dest = 0; 504 505 return NO_ERROR; 506} 507 508 509int gethostname(char *buf, int len) { 510 GetComputerName(buf,(DWORD*)&len); 511 return 0; 512} 513int nt_chdir (char *path) { 514 char *tmp = path; 515 if (gdwPlatform !=VER_PLATFORM_WIN32_NT) { 516 while(*tmp) { 517 if (*tmp == '/') *tmp = '\\'; 518 tmp++; 519 } 520 } 521 return _chdir(path); 522} 523void WINAPI uhef( EXCEPTION_POINTERS *lpep) { 524 ExitProcess(lpep->ExceptionRecord->ExceptionCode); 525} 526extern BOOL CreateWow64Events(DWORD,HANDLE*,HANDLE*,BOOL); 527// load kernel32 and look for iswow64. if not found, assume FALSE 528BOOL bIsWow64Process = FALSE; 529void init_wow64(void) { 530 HMODULE hlib; 531 //BOOL (WINAPI *pfnIsWow64)(HANDLE,BOOL*); 532 FARPROC pfnIsWow64; 533 534 bIsWow64Process = FALSE; 535 536 hlib = LoadLibrary("kernel32.dll"); 537 if (!hlib) { 538 return; 539 } 540 pfnIsWow64 = GetProcAddress(hlib,"IsWow64Process"); 541 if (!pfnIsWow64) { 542 FreeLibrary(hlib); 543 return; 544 } 545 if (!pfnIsWow64(GetCurrentProcess(),&bIsWow64Process) ) 546 bIsWow64Process = FALSE; 547 548 FreeLibrary(hlib); 549 return; 550 551} 552 553extern void mainCRTStartup(void *); 554 555/* 556 * heap_init() MUST NOT be moved outside the entry point. Sometimes child 557 * processes may load random DLLs not loaded by the parent and 558 * use the heap address reserved for fmalloc() in the parent. This 559 * causes havoc as no dynamic memory can then be inherited. 560 * 561 */ 562extern void heap_init(void); 563 564#include <forkdata.h> 565void silly_entry(void *peb) { 566 char * path1=NULL; 567 int rc; 568 char temp[MAX_PATH+5]; 569 char buf[MAX_PATH]; 570 char ptr1[MAX_PATH]; 571 char ptr2[MAX_PATH]; 572 char ptr3[MAX_PATH]; 573 OSVERSIONINFO osver; 574 575 osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 576 577 if (!GetVersionEx(&osver)) { 578 MessageBox(NULL,"GetVersionEx failed","tcsh",MB_ICONHAND); 579 ExitProcess(0xFF); 580 } 581 gdwVersion = osver.dwMajorVersion; 582 583 if(gdwVersion < 6) // no wow64 hackery for vista. 584 { 585 init_wow64(); 586 } 587 588#ifdef _M_IX86 589 // look at the explanation in fork.c for why we do these steps. 590 if (bIsWow64Process) { 591 HANDLE h64Parent,h64Child; 592 char *stk, *end; 593 DWORD mb = (1<<20); 594 595 // if we found the events, then we're the product of a fork() 596 if (CreateWow64Events(GetCurrentProcessId(), 597 &h64Parent,&h64Child,TRUE)) { 598 599 if (!h64Parent || !h64Child) 600 return; 601 602 // tell parent we're rolling 603 SetEvent(h64Child); 604 605 if(WaitForSingleObject(h64Parent,FORK_TIMEOUT) != WAIT_OBJECT_0) { 606 return; 607 } 608 609 // if __forked is 0, we shouldn't have found the events 610 if (!__forked) 611 return; 612 } 613 614 // now create the stack 615 616 if (!__forked) { 617 stk = VirtualAlloc(NULL,mb+65536,MEM_COMMIT,PAGE_READWRITE); 618 if (!stk) { 619 dprintf("virtual alloc in parent failed %d\n",GetLastError()); 620 return; 621 } 622 end = stk + mb + 65536; 623 end -= sizeof(char*); 624 625 __fork_stack_begin = end; 626 627 __asm {mov esp,end }; 628 629 set_stackbase(end); 630 heap_init(); 631 } 632 else { // child process 633 stk = (char*)__fork_stack_begin + sizeof(char*)- mb - 65536; 634 635 dprintf("begin is 0x%08x\n",stk); 636 end = VirtualAlloc(stk, mb+65536 , MEM_RESERVE , PAGE_READWRITE); 637 if (!end) { 638 rc = GetLastError(); 639 dprintf("virtual alloc 1 in child failed %d\n",rc); 640 return; 641 } 642 stk = VirtualAlloc(end, mb+65536 , MEM_COMMIT , PAGE_READWRITE); 643 if (!stk) { 644 rc = GetLastError(); 645 dprintf("virtual alloc 2 in child failed %d\n",rc); 646 return; 647 } 648 end = stk + mb + 65536; 649 __asm {mov esp, end}; 650 set_stackbase(end); 651 652 SetEvent(h64Child); 653 654 CloseHandle(h64Parent); 655 CloseHandle(h64Child); 656 } 657 } 658#endif _M_IX86 659 660 661 SetFileApisToOEM(); 662 663 if (!bIsWow64Process) 664 heap_init(); 665 666 667 668 669 /* If home is set, we only need to change '\' to '/' */ 670 rc = GetEnvironmentVariable("HOME",buf,MAX_PATH); 671 if (rc && (rc < MAX_PATH)){ 672 path_slashify(buf); 673 (void)SetEnvironmentVariable("HOME",buf); 674 goto skippy; 675 } 676 677 memset(ptr1,0,MAX_PATH); 678 memset(ptr2,0,MAX_PATH); 679 memset(ptr3,0,MAX_PATH); 680 681 if(osver.dwPlatformId == VER_PLATFORM_WIN32_NT) { 682 GetEnvironmentVariable("USERPROFILE",ptr1,MAX_PATH); 683 GetEnvironmentVariable("HOMEDRIVE",ptr2,MAX_PATH); 684 GetEnvironmentVariable("HOMEPATH",ptr3,MAX_PATH); 685 686 ptr1[MAX_PATH -1] = ptr2[MAX_PATH-1] = ptr3[MAX_PATH-1]= 0; 687 688#pragma warning(disable:4995) 689 if (!ptr1[0] || osver.dwMajorVersion <4) { 690 wsprintfA(temp, "%s%s",ptr2[0]?ptr2:"C:",ptr3[0]?ptr3:"\\"); 691 } 692 else if (osver.dwMajorVersion >= 4) { 693 wsprintfA(temp, "%s",ptr1); 694 } 695#pragma warning(default:4995) 696 } 697 else if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { 698 699 rc = GetWindowsDirectory(ptr1,MAX_PATH); 700 if (rc > MAX_PATH) { 701 MessageBox(NULL,"This should never happen","tcsh",MB_ICONHAND); 702 ExitProcess(0xFF); 703 } 704 (void)StringCbPrintf(temp,sizeof(temp),"%s",ptr1); 705 } 706 else { 707 MessageBox(NULL,"Unknown platform","tcsh",MB_ICONHAND); 708 } 709 path_slashify(temp); 710 SetEnvironmentVariable("HOME",temp); 711 712skippy: 713 gdwPlatform = osver.dwPlatformId; 714 715 716 rc = GetEnvironmentVariable("Path",path1,0); 717 if ( rc !=0) { 718 719 path1 =heap_alloc(rc); 720 721 GetEnvironmentVariable("Path",path1,rc); 722 SetEnvironmentVariable("Path",NULL); 723 /*SetEnvironmentVariable("PATH",NULL);*/ 724 SetEnvironmentVariable("PATH",path1); 725 726 heap_free(path1); 727 } 728 mainCRTStartup(peb); 729} 730 731/* 732 * Copy source into target, quote if it has space, also converting '/' to '\'. 733 * 734 * hasdot is set to 1 if source ends in a file extension 735 * return value is the length of the string copied. 736 */ 737int copy_quote_and_fix_slashes(char *source,char *target, int *hasdot ) { 738 739 int len ; 740 int hasspace; 741 char *save; 742 char *ptr; 743 744 save = target; /* leave space for quote */ 745 len = 1; 746 747 target++; 748 749 hasspace = 0; 750 while(*source) { 751 if (*source == '/') 752 *source = '\\'; 753 else if (*source == ' ') 754 hasspace = 1; 755 756 *target++ = *source; 757 758 source++; 759 len++; 760 } 761 ptr = target;//source; 762 while( (ptr > save ) && (*ptr != '\\')) { 763 if (*ptr == '.') 764 *hasdot = 1; 765 ptr--; 766 } 767 768 if (hasspace) { 769 *save = '"'; 770 *target = '"'; 771 len++; 772 } 773 return len; 774} 775/* 776 * This routine is a replacement for the old, horrible strcat() loop 777 * that was used to turn the argv[] array into a string for CreateProcess(). 778 * It's about a zillion times faster. 779 * -amol 2/4/99 780 */ 781char *concat_args_and_quote(char **args, char **poriginalPtr,char **cstr, 782 unsigned int *clen, char **cend, unsigned int *cmdsize) { 783 784 unsigned int argcount, arglen, cmdlen; 785 char *tempptr, *cmdend ,*cmdstr; 786 short quotespace = 0; 787 short quotequote = 0; 788 short noquoteprotect = 0; 789 char *tempquotedbuf; 790 unsigned long tqlen = 256; 791 int rc; 792 793 dprintf("entering concat_args_and_quote\n"); 794 tempquotedbuf = heap_alloc(tqlen); 795 796 noquoteprotect = (short)(varval(STRNTnoquoteprotect) != STRNULL); 797 /* 798 quotespace hack needed since execv() would have separated args, but 799 createproces doesnt 800 -amol 9/14/96 801 */ 802 cmdend= *cend; 803 cmdstr = *cstr; 804 cmdlen = *clen; 805 806 argcount = 0; 807 while (*args) { 808 809 *cmdend++ = ' '; 810 cmdlen++; 811 812 tempptr = *args; 813 814 arglen = 0; 815 argcount++; 816 817 //dprintf("args is %s\n",*args); 818 if (!*tempptr) { 819 *cmdend++ = '"'; 820 *cmdend++ = '"'; 821 } 822 while(*tempptr) { 823 if (*tempptr == ' ' || *tempptr == '\t') 824 quotespace = 1; 825 else if (*tempptr == '"') 826 quotequote = 1; 827 tempptr++; 828 arglen++; 829 } 830 if (arglen + cmdlen +4 > *cmdsize) { // +4 is if we have to quote 831 832 833 tempptr = heap_realloc(*poriginalPtr,*cmdsize<<1); 834 835 if(!tempptr) 836 return NULL; 837 838 // If it's not the same heap block, re-adjust the pointers. 839 if (tempptr != *poriginalPtr) { 840 cmdstr = tempptr + (cmdstr - *poriginalPtr); 841 cmdend = tempptr + (cmdend- *poriginalPtr); 842 *poriginalPtr = tempptr; 843 } 844 845 *cmdsize <<=1; 846 } 847 if (quotespace) 848 *cmdend++ = '"'; 849 850 if ((noquoteprotect == 0) && quotequote){ 851 tempquotedbuf[0]=0; 852 853 tempptr = &tempquotedbuf[0]; 854 855 rc = quoteProtect(tempquotedbuf,*args,tqlen); 856 857 while(rc == ERROR_BUFFER_OVERFLOW) { 858 char *tmp = tempquotedbuf; 859 tempquotedbuf = heap_realloc(tempquotedbuf,tqlen <<1); 860 if(!tempquotedbuf) { 861 heap_free(tmp); 862 return NULL; 863 } 864 tqlen <<= 1; 865 tempptr = &tempquotedbuf[0]; 866 rc = quoteProtect(tempquotedbuf,*args,tqlen); 867 } 868 while (*tempptr) { 869 *cmdend = *tempptr; 870 cmdend++; 871 tempptr++; 872 } 873 cmdlen +=2; 874 } 875 else { 876 tempptr = *args; 877 while(*tempptr) { 878 *cmdend = *tempptr; 879 cmdend++; 880 tempptr++; 881 } 882 } 883 884 if (quotespace) { 885 *cmdend++ = '"'; 886 cmdlen +=2; 887 } 888 cmdlen += arglen; 889 890 args++; 891 } 892 *clen = cmdlen; 893 *cend = cmdend; 894 *cstr = cmdstr; 895 896 heap_free(tempquotedbuf); 897 898 899 return cmdstr; 900} 901char *fix_path_for_child(void) { 902 903 char *ptr; 904 Char *vp; 905 char *pathstr; 906 char *oldpath; 907 long len; 908 909 vp = varval(STRNTlamepathfix); 910 911 if (vp != STRNULL) { 912 913 len = GetEnvironmentVariable("PATH",NULL,0); 914 915 oldpath = heap_alloc(len+1); 916 pathstr = heap_alloc(len+1); 917 918 len = GetEnvironmentVariable("PATH",oldpath,len+1); 919 memcpy(pathstr,oldpath,len); 920 921 ptr = pathstr; 922 while(*ptr) { 923 if (*ptr == '/') 924 *ptr = '\\'; 925 ptr++; 926 } 927 SetEnvironmentVariable("PATH",pathstr); 928 heap_free(pathstr); 929 930 return oldpath; //freed in restore_path; 931 } 932 else 933 return NULL; 934 935} 936void restore_path(char *oldpath) { 937 if (oldpath) { 938 SetEnvironmentVariable("PATH",oldpath); 939 heap_free(oldpath); 940 } 941} 942