aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
Diffstat (limited to 'win32')
-rw-r--r--win32/BSDLOGO.BMPbin0 -> 3698 bytes
-rw-r--r--win32/BSDLOGO.ICObin0 -> 766 bytes
-rw-r--r--win32/BSDLOGO.RC2
-rw-r--r--win32/CODING20
-rw-r--r--win32/ChangeLog686
-rw-r--r--win32/Contributors15
-rw-r--r--win32/Makefile.win32285
-rw-r--r--win32/README.NT605
-rw-r--r--win32/WindowsReadme.1st556
-rw-r--r--win32/bogus.c168
-rw-r--r--win32/clip.c570
-rw-r--r--win32/console.c636
-rw-r--r--win32/customstep.cmd7
-rw-r--r--win32/dirent.c364
-rw-r--r--win32/dirent.h72
-rw-r--r--win32/example.tcshrc211
-rw-r--r--win32/fork.c614
-rw-r--r--win32/forkdata.h76
-rw-r--r--win32/globals.c222
-rw-r--r--win32/io.c479
-rw-r--r--win32/msg/Makefile49
-rw-r--r--win32/msg/makerc.pl43
-rw-r--r--win32/msg/makercjp.pl31
-rw-r--r--win32/msg/makercrc.pl35
-rw-r--r--win32/msg/stubdll.c7
-rw-r--r--win32/msg/test.c33
-rw-r--r--win32/nt.bind.c1351
-rw-r--r--win32/nt.char.c127
-rw-r--r--win32/nt.const.c50
-rw-r--r--win32/nt.screen.c539
-rw-r--r--win32/nt.who.c275
-rw-r--r--win32/ntb1.c35
-rw-r--r--win32/ntb2.c34
-rw-r--r--win32/ntfunc.c1207
-rw-r--r--win32/ntport.h511
-rw-r--r--win32/ps.c371
-rw-r--r--win32/signal.c728
-rw-r--r--win32/signal.h125
-rw-r--r--win32/stdio.c628
-rw-r--r--win32/support.c941
-rw-r--r--win32/tcshrc.rc99
-rw-r--r--win32/version.h14
42 files changed, 12821 insertions, 0 deletions
diff --git a/win32/BSDLOGO.BMP b/win32/BSDLOGO.BMP
new file mode 100644
index 000000000000..f45c05863153
--- /dev/null
+++ b/win32/BSDLOGO.BMP
Binary files differ
diff --git a/win32/BSDLOGO.ICO b/win32/BSDLOGO.ICO
new file mode 100644
index 000000000000..914714f5128b
--- /dev/null
+++ b/win32/BSDLOGO.ICO
Binary files differ
diff --git a/win32/BSDLOGO.RC b/win32/BSDLOGO.RC
new file mode 100644
index 000000000000..2973a877b203
--- /dev/null
+++ b/win32/BSDLOGO.RC
@@ -0,0 +1,2 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/BSDLOGO.RC,v 1.3 2004/05/19 18:22:27 christos Exp $*/
+IDI_ICON1 ICON DISCARDABLE "win32/BSDLOGO.ICO"
diff --git a/win32/CODING b/win32/CODING
new file mode 100644
index 000000000000..212a22b67d7f
--- /dev/null
+++ b/win32/CODING
@@ -0,0 +1,20 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/CODING,v 1.3 2004/05/19 18:22:27 christos Exp $*/
+Read this if you plan to contribute changes to the source:
+
+Please do not use any heap allocation routine other than:
+
+1. heap_alloc()/heap_free(), if the memory will never be acessed in a child
+process (i.e, is not expected to be inherited). this is a macro defined
+in ntport.h
+
+2. xmalloc()/xfree(), if the memory is to be inherited by a child process.
+this is allocated from a seperate heap and is copied to the child during fork().
+
+Avoid using C-runtime functions that store static variables
+(like strtok, for example).
+
+It is preferrable to avoid any c-runtime function other than strlen,strcat
+etc.
+
+Thanks.
+-amol
diff --git a/win32/ChangeLog b/win32/ChangeLog
new file mode 100644
index 000000000000..d878ef5d8bb7
--- /dev/null
+++ b/win32/ChangeLog
@@ -0,0 +1,686 @@
+Rev 7.00
+Sun Aug 11 00:39:38 2002 <amol@AMOLDWHISPHOME>
+ * various files: Remove GPL'ed termcap code. Partial fix for
+ horizontal scroll. Fix visiblebell.
+Sat May 04 22:38:36 2002 <amol@AMOLDWHISPHOME>
+ * ntfunc.c: fixed leak in nt_texec ?? (fast exec path).
+ Removed sourcerc and printrc.
+Rev 6.07
+Mon Mar 18 17:54:44 2002 <amol@AMOLDWHISPHOME>
+ * support.c,fork.c: wow64 (32-bit on ia64) seems to work now.
+Rev 6.06
+Sun Mar 17 21:25:28 2002 <amol@AMOLDWHISPHOME>
+ * support.c,fork.c: attempt wow64 support.
+Rev 6.05
+Sat Mar 16 10:53:21 2002 <amol@AMOLDWHISPHOME>
+
+ * console.c: Fix refreshing problems with searching history.
+
+Rev 6.04
+Fri Mar 01 18:52:30 2002 <amol@AMOLDWHISPHOME>
+
+ * ntfunc.c: Fix another bug. Some associated files were launched twice.
+
+Rev 6.03
+Mon Feb 18 19:24:47 2002 <amol@AMOLDWHISPHOME>
+
+ * ntfunc.c,support.c: Of course, fix bug introduced by previous fix.
+ (#! emulation was broken)
+
+Rev 6.02
+Sun Feb 17 15:10:50 2002 <amol@AMOLDWHISPHOME>
+ * various files, many fixes,
+ 1. SetFileApisToOEM: Fix display problems with Euro filenames.
+ 2. Try explorer associations in fast exec path as well.
+ 3. Fix bug with TCSHONLYSTARTEXES not working for extensions less
+ than 3 chars
+ 4. Fix bug with e_page_up/down that always made them beep.
+ 5. Fix bug related to backward-search refreshing problem
+Wed Oct 10 21:58:50 2001 <amold@AMOLDHOME>
+ * win32\clip.c: Fix bug in redirection to /dev/clipboard. it should work
+ now.
+Rev 6.00
+Thu Aug 16 18:55:54 2001 <amold@AMOLDHOME>
+ * win32\clip.c: Integrate with 6.10.02, put e_copy_from_clipboad and
+ e_paste_from_clipboard back. Document N-S binding in README.NT.
+Rev 5.56,5.57
+Tue Jun 19 22:13:52 2001 <amold@AMOLDHOME>
+ * various files: Remove stacksize builtin. Shift keymap. Sync with
+ tcsh-6.10.01. e_undosify etc.
+Rev 5.55
+Wed Mar 28 17:19:06 2001 <amold@AMOLDHOME>
+ * misc files: add sourcerc and printrc builtins
+Rev 5.54
+Sat Jan 27 18:45:20 2001 <amold@AMOLDHOME>
+ * win32\ps.c: Fixed bug that made ps crash on NT 4.0
+Rev 5.53
+Thu Nov 30 14:30:03 2000 <amold@SKYNYRD>
+ * win32\ntfunc.c: 6.10, fix bug in 'start' and TCSHONLYSTARTEXES
+Rev 5.52
+Wed Nov 15 03:54:03 2000 <Administrator@AMOLDHOME>
+ * misc files: integrate 6.09.04
+Rev 5.51
+Thu Jul 20 19:25:41 2000 <amold@AMOLDHOME>
+ * win32\ps.c: Fix bug in ps.c
+Rev 5.50
+Fri Jul 14 20:33:33 2000 <amold@AMOLDHOME>
+ * various: Fix TCSHONLYSTARTEXES and completion. add e_page_up
+ and e_page_down editor functions. Some 64-bit work.
+Rev 5.49
+Mon Jun 05 17:42:55 2000 <amold@SKYNYRD>
+ * win32\ntfunc.c: move executable() to NT source.
+Rev 5.48
+Mon May 29 14:22:03 2000 <amold@SKYNYRD>
+ * various files: Finally integrate patches for "start <directory>".
+ Also, completions will recognize extensions from TCSHONLYSTARTEXES
+Rev 5.46
+Wed Mar 01 10:32:22 2000 <amold@SKYNYRD>
+ * win32\ntfunc.c,win32\support.c: Make NTlamepathfix consistent
+ across fast exec, launched associations as well as normal
+ command execution.
+Rev 5.45
+Fri Jan 07 11:50:03 2000 <amold@SKYNYRD>
+ * win32\support.c, ntfunc.c, Makefile.win32: Remove stack probing
+ in fork() by commiting 1/2MB of the thread stack instead of the
+ default page size. To reduce the footprint of spawned threads
+ (for clipboard or SIGCHILD), a new builtin stacksize has been
+ added.
+Rev 5.44
+Thu Jan 06 12:28:55 2000 <amold@SKYNYRD>
+ * win32\stdio.c: Fixed serious bug that would cause backticked
+ expressions in shell scripts to not run. Should also fix hangs
+ with piped builtins like "bindkey | wc -l"
+Rev 5.43
+Fri Oct 29 11:10:58 1999 <amold@SKYNYRD>
+ * win32\support.c: added NTnoquoteprotect variable.
+Rev 5.42
+Sun Oct 24 11:52:06 1999 <amold@SKYNYRD>
+ * win32\ntfunc.c: Fix $? on fast exec path.
+Rev 5.41
+Fri Oct 08 11:08:41 1999 <amold@SKYNYRD>
+ * win32\support.c: Support for NTcaseifypwd
+Rev 5.37
+Fri Apr 02 11:51:54 1999 <amold@SKYNYRD>
+ * tc.func.c: Fixed bug that showed files in ls //server/share
+ as directories.
+Rev 5.36
+Wed Mar 24 14:36:50 1999 <amold@SKYNYRD>
+ * tc.func.c, win32\stdio.c: Cleaned up code. fixed bug
+ that would prevent ls //unc (introduced in 5.35, of course).
+Rev 5.34,5.35
+Tue Mar 23 12:07:52 1999 <amold@SKYNYRD>
+ * various files: Fix for ls c:/bin/* and paths with spaces
+Rev 5.33
+Wed Mar 17 12:37:50 1999 <amold@SKYNYRD>
+ * win32\support.c: Fix bug to resume converting $HOME to
+ '/'-delimited.
+Mon Mar 15 11:15:51 1999 <amold@SKYNYRD>
+ * sh.func.c: Make setting environment variables case-insensitve
+Rev 5.321
+Mon Mar 15 09:46:34 1999 <amold@SKYNYRD>
+ * win32\ntfunc.c: remove stupid hardcoded breakpoint. Hit when
+ executing scripts, batch files, etc.
+Rev 5.32
+Sat Mar 13 12:58:34 1999 <amold@SKYNYRD>
+ * various files: Use hashtable to check command spelling. Will
+ eliminate bogus corrections on NT. Code re-org in support.c.
+ Also backed out agressive correction introduced in 5.29.
+Rev 5.29
+Tue Feb 09 16:23:39 1999 <amold@SKYNYRD>
+ * tw.parse.c,tw.spell.c: Aggressive spelling correction. Apppend
+ ".exe" to a command while doing spellcheck.
+Rev 5.28
+Wed Feb 03 16:58:46 1999 <amold@SKYNYRD>
+ * various files: speed up argument parsing in exec. should
+ make commands with long argument strings run considerably faster.
+ Speed up argument parsing for the start builtin as above. remove
+ shell limit on command length.
+ Code cleanups, move heap_init() to executable entry point instead
+ of fork_init() to prevent heap conflicts in child processes.
+Rev 5.27
+Fri Jan 08 10:36:24 1999 <amold@SKYNYRD>
+ * win32\io.c: ignore ctrl-space and ctrl-@ if NOREBIND
+ is not set. This should fix the bug which caused altgr-q
+ to not work, for example.
+Rev 5.261
+Fri Nov 20 15:34:32 1998 <amold@SKYNYRD>
+ * sh.sem.c: fixed stupid bug that neutralized the fast exec
+ path. set NTslowexec if you get funky behaviour from the shell.
+Rev 5.26
+Fri Nov 20 15:13:51 1998 <amold@SKYNYRD>
+ * ed.refresh.c: Patch from taga nayuta for fixing problems
+ with rprompt and prompt both having ANSI escapes.
+Rev 5.25
+Tue Nov 03 12:23:20 1998 <amold@SKYNYRD>
+ * win32\support.c: Win9x-specific fix for apps which may
+ have been started from a directory with a '.' in the name, but
+ without specifying the extension. e.g., c:/foo.bar/baz
+Rev 5.24
+Sat Oct 31 16:12:20 1998 <amold@SALEMS_LOT>
+ * tc.bind.c,win32\nt.bind.c: Bindkey extensions for N-C
+ N-M. See README.NT for details. Fixed bug in clipboard
+ pasting on win95
+Rev 5.23
+Fri Oct 16 12:51:25 1998 <amold@SKYNYRD>
+ * win32\support.c: improve support for win32 GUI app
+ detection on Win9x (for TCSH_NOASYNCGUI).
+Rev 5.21
+Tue Oct 06 12:15:30 1998 <amold@SKYNYRD>
+ * sh.dir.c,sh.exec.c: Synced with tcsh-6.08 and applied
+ patches to that same. (setenv HOME foo crash, and
+ compilation problem with sh.exec.c)
+Rev 5.202
+Thu Oct 01 11:55:53 1998 <amold@SKYNYRD>
+ * win32\io.c, sh.exec.c: KANJI+multibyte fixes from
+ taga nayuta.
+ Fix for "where" failing with directories that had '.' in
+ their name.
+Rev 5.18
+Fri Sep 11 08:21:18 1998 <amold@SKYNYRD>
+ * win32\clip.c: Fixed bug that caused crashes when pasting
+ international characters from clipboard using e_paste...
+Rev 5.17
+Tue Sep 08 11:04:35 1998 <amold@SKYNYRD>
+ * tc.func.c: Bugfix for hang when rmstar is set.
+Rev 5.16
+Wed Aug 26 10:18:42 1998 <amold@SKYNYRD>
+ * win32\ntfunc.c,sh.dir.c: Fixed bug in interaction between
+ TCSHONLYSTARTEXES and "start". Fixed bug that caused a crash
+ if you tried set home=C:\\ (which is WRONG anyway).
+Rev 5.15
+Tue Aug 04 14:48:32 1998 <amold@SKYNYRD>
+ * ed.chared.c,ed.defns.c,ed.decls.h: Added e_dosify_prev. See
+ README.NT for details.
+Rev 5.14
+Tue Jul 28 10:17:53 1998 <amold@SKYNYRD>
+ * win32\ntfunc.c: change in behaviour of TCSHONLYSTARTEXES. Please
+ check README.NT for details.
+Rev 5.12
+Sat Jul 18 13:12:39 1998 <amold@SKYNYRD>
+ * win32\ntfunc.c: Patch from taga nayuta for start <URL>
+Rev 5.11
+Tue Jul 14 15:55:32 1998 <amold@SKYNYRD>
+ * ed.screen.c: Changed literal spec. in prompt to use ANSI
+ sequences instead of old hack. This is made necessary by the
+ color-ls patch. It does not make any sense to have two methods
+ of parsing these strings.
+Rev 5.10
+Tue Jul 14 12:40:41 1998 <amold@SKYNYRD>
+ * sh.sem.c: Check for NTslowexec before mangling the syntax
+ tree.
+Rev 5.09
+Sun Jul 12 17:13:09 1998 <amold@SALEMS_LOT>
+ * win32\io.c,console.c: patches from TAGA nayuta. Includes fix for
+ clear-screen, color-ls and ctrl-space, ctrl-@
+Rev 5.04-5.08
+Sat Jul 11 21:19:47 1998 <amold@SALEMS_LOT>
+ * win32\signal.c: Hacked signal mechanism to deliver signal in
+ the main thread. May cause crashes/hangs. Can be compiled out.
+Rev 5.03
+Wed Jul 08 17:06:41 1998 <amold@SKYNYRD>
+ * ed.refresh.c: Fixed bug in edit-time refresh of lines > 1 line.
+Rev 5.02
+Mon Jul 06 11:08:12 1998 <amold@SKYNYRD>
+ * various: separated nt-specific builtins from the rest of the
+ shell. Makes maintainence easier.
+Rev 5.00
+Tue Jun 30 14:46:26 1998 <amold@SKYNYRD>
+ * various: synced with tcsh-6.07.08. Fixed bug in alias
+ interactions with fast exec. make settc work with li and
+ co.
+Rev 4.09
+Mon Jun 01 13:54:05 1998 <amold@SKYNYRD>
+ * win32\ntfunc.c: Fixed fast exec path to use the hash
+Rev 4.07
+Sat May 30 13:37:26 1998 <amold@SKYNYRD>
+ * sh.sem.c: Fixed bug in dollar expansion in the fast exec
+ path.
+ * win32\clip.c: Removed 4Kb clipboard limitation.
+
+ Misc. code cleanup.
+Rev 4.05
+Thu May 28 14:17:57 1998 <amold@SKYNYRD>
+ * win32\support.c,win32\ntfunc.c,sh.sem.c: Fixed bug that
+ prevented execution of programs whose path had spaces in them.
+ Added optimization for simple commands to avoid fork(). Please
+ read about NTslowexec in README.NT if you see any weird
+ behaviour from the shell.
+Rev 4.03
+Fri May 22 08:19:32 1998 <amold@SKYNYRD>
+ * win32\support.c: Fixed parsing of quoted args to child processes.
+ hopefully.
+Rev 4.02
+Thu May 14 18:52:22 1998 <amold@SKYNYRD>
+ * win32\support.c: Fixed bug that caused UNC-path-exes to be
+ spawned in a new window. Also fixed wildcard expansion bug
+ (ls *.c ) caused by merge with standard distribution.
+Rev 4.0
+Thu Apr 23 09:49:28 1998 <amold@SKYNYRD>
+
+ * tcsh-6.07.06 pre-release. Please try it out and see if
+ anything got broken in integration.
+
+rev 3.661
+Fri Apr 10 16:48:04 1998 <amold@SKYNYRD>
+ * tc.const.c: Changed NTONLYSTARTEXES to TCSHONLYSTARTEXES. really.
+rev 3.66
+Sat Apr 04 15:22:02 1998 <amold@SKYNYRD>
+ * win32\support.c: fixed bug that was restricting command line
+ lengths.
+Rev 3.652
+Fri Mar 27 11:26:24 1998 <amold@SKYNYRD>
+ * tc.prompt.c: Keep server names in prompt when %C is specified.
+ * win32\ntfunc.c: Fixed crash in the start builtin when options
+ were specified but no command.
+Rev 3.651
+Tue Mar 24 17:53:32 1998 <amold@SKYNYRD>
+ * win32\ntfunc.c: Took out 512-char limit in setenv.
+Rev 3.65
+Wed Mar 11 09:26:43 1998 <amold@SKYNYRD>
+ * sh.h: Fixed bug that caused problem with 'which' or
+ crashed the shell when a path component did not have
+ the drive letter. e.g., '/bin' or set home=/foo
+Rev 3.643
+Sun Mar 08 12:55:04 1998 <amold@SKYNYRD>
+ * sh.dir.c: Fixed crash in echo `dirs`
+Rev 3.641
+Sat Feb 21 12:06:18 1998 <amold@SALEMS_LOT>
+ * win32\support.c: NTONLYSTARTEXES changed to TCSHONLYSTARTEXES
+ NTlameargfix done by default. The variable has no effect now.
+ Both changes due to major restructuring of execve(). It's faster,
+ but probably not appreciable to the human eye.
+
+Rev 3.64
+Fri Feb 20 17:08:27 1998 <amold@SKYNYRD>
+ * win32\support.c: cleaned up execve(), fixed crash in win95 when
+ trying file associations.
+ (cleanup may have introduced bugs, be careful)
+Rev 3.63
+Thu Feb 12 10:07:10 1998 <amold@SKYNYRD>
+ * win32\ps.c: psapi.dll no longer needed, but will be used if
+ it exists (of course, Windows NT only).
+Rev 3.62
+Thu Feb 05 11:31:56 1998 <amold@SKYNYRD>
+ * win32\ps.c: Added -3 argument for the kill builtin. This will
+ send a WM_CLOSE message to the app's window. May be a useful
+ way to shut down GUI apps. tcsh itself can also be killed
+ with this "signal" (maps to a SIGHUP or CTRL_CLOSE_EVENT).
+
+Rev 3.612
+Fri Jan 30 14:29:44 1998 <amold@SKYNYRD>
+ * sh.proc.c: Changed kill to take hex pid (0xff...) as well
+ Probably helps on win95 if you use the builtin ps
+ to list processes.
+Rev 3.611
+Tue Jan 27 17:48:02 1998 <amold@SKYNYRD>
+ * win32\support.c: of course, the /dev/clipboard stuff had
+ a bug.
+Rev 3.61
+Tue Jan 27 14:04:21 1998 <amold@SKYNYRD>
+ * win32\clip.c,win32\stdio.c: Hack to treat /dev/clipboard
+ as a special case for i/o redirection. Limit of 4K, not fully
+ tested. Use at your own risk. Idea by David Sinck.
+Rev 3.60
+Tue Jan 27 09:06:41 1998 <amold@SKYNYRD>
+ * ed.chared.c,ed.defns.c: added e_dosify_next editor function
+ to enable converting '/'-delimited paths to '\'-delimited.
+ For those times when you just have to use xcopy.
+Rev 3.59
+Thu Jan 22 11:16:00 1998 <amold@SKYNYRD>
+ * win32\globals.c,support.c: Added support for starting
+ GUI apps asynchronously (don't wait for them to terminate).
+ Can be overridden by setting TCSH_NOASYNCGUI to a non-zero
+ length. Also put in logic to try appending ".exe" as well
+ as ".EXE" to a command. This is for some case-sensitive
+ filesystem drivers out there.
+Rev 3.581
+Fri Jan 02 10:26:16 1998 <amold@SKYNYRD>
+
+ * win32\clip.c: Fixed minor bugs and removed shared kill buffer
+ code. Only the clipboard can be used to share data now. See
+ README.NT for details on how to use the clipboard.
+
+Rev 3.58
+Wed Dec 31 13:26:40 1997 <amold@SKYNYRD>
+ * ed.defns.c,win32\clip.c: Added support for the clipboard
+ functions. Disabled shared kill buffers
+Rev 3.57
+Tue Dec 30 17:42:27 1997 <amold@SKYNYRD>
+ * ed.chared.c,win32\support.c: Experimental sharing of
+ kill buffers among all active instances of tcsh.
+ I'm not sure how well this works yet.
+Rev 3.563
+Tue Dec 30 10:32:34 1997 <amold@SKYNYRD>
+ * sh.func.c: Fixed bug in unsetenv (it wasn't working at all).
+Rev 3.561
+Mon Dec 29 11:57:16 1997 <amold@SKYNYRD>
+ * win32\ps.c: Fixed bug in ps. Also added manadatory
+ "now" argument to shutdown.
+Rev 3.56
+Tue Dec 23 14:05:16 1997 <amold@SKYNYRD>
+ * win32\ps.c: Added shutdown builtin.
+Rev 3.55
+Fri Dec 19 13:28:25 1997 <amold@SKYNYRD>
+ * win32\ps.c: Added ps builtin.
+Rev 3.544
+Fri Dec 12 13:41:52 1997 <amold@SKYNYRD>
+ * tw.parse.c: Fixed bug in complete=igncase
+Rev 3.543
+Wed Dec 10 14:01:12 1997 <amold@SKYNYRD>
+ * win32\io.c: Fix for redirecting to /dev/null.
+Rev 3.542
+Wed Dec 03 10:15:45 1997 <amold@SKYNYRD>
+ * win32\io.c: Fix for spurious CR's on win95 when
+ running commands that read from stdin.
+Rev 3.541
+Tue Nov 25 11:22:05 1997 <amold@SKYNYRD>
+ * win32\ntfunc.c: Fix for some bugs with NTONLYSTARTEXES
+Rev 3.54
+Mon Nov 24 15:32:45 1997 <amold@SKYNYRD>
+ * tc.const.c,sh.func.c: Added environment variable
+ NTONLYSTARTEXES, which can be set on the fly, to
+ control whether associations (e.g., notepad with .txt)
+ should be recognized.
+Recv 3.53
+Mon Nov 24 13:17:04 1997 <amold@SKYNYRD>
+ * misc files: Changed copyright to Berkeley. Fixed minor
+ bugs.
+Rev 3.52
+Fri Nov 21 09:41:03 1997 <amold@SKYNYRD>
+ * win32\fork.c: Fixed bug in environment inheritance.
+Rev 3.51
+Mon Nov 17 14:51:57 1997 <amold@SKYNYRD>
+ * tc.func.c: Fix for ls //server
+Rev 3.4,3.5
+Fri Nov 14 09:34:13 1997 <amold@SKYNYRD>
+ * misc: Integrated into standard distribution.
+ Feeping creaturism: Added support for file associations.
+ e.g, start foo.txt will start notepad with foo.txt etc.
+Rev 3.325
+Tue Oct 28 16:38:03 1997 <amold@SKYNYRD>
+ * sh.h: Fix to make $$ inherited by child process. The bug
+ showed up in tcsh <infile>out.$$, for example
+Rev. 3.323,3.324
+Wed Oct 22 13:06:59 1997 <amold@SKYNYRD>
+ * ntport\support.c: Made hack below a little smarter. Add '.'
+ only if the command is not found by the usual search.
+ * ntport\ntfunc.c: Fix to pass arguments on to batch files
+Rev. 3.322
+Wed Oct 15 14:37:22 1997 <amold@SKYNYRD>
+ * ntport\support.c: Win95-only hack to add '.' to the end
+ of a command that does not have any '.'-s.
+Rev. 3.321
+Mon Oct 13 09:47:35 1997 <amold@SKYNYRD>
+
+ * sh.func.c: Fix for TCSHSUBSTHB when the #! command contains only
+ one word.
+ * ntport\support.c: Fix for paths with "./" instead of "." on
+ win95.
+
+Rev 3.32
+Thu Oct 09 17:01:30 1997 <amold@SKYNYRD>
+
+ * ntport\ntfunc.c,sh.func.c: Hacks for TCSHSUBSTHB. See README.NT
+ for details. Allegedly makes it easier to run scripts directly
+ from Unix.
+
+Rev 3.31
+Mon Oct 06 18:22:10 1997 <amold@SKYNYRD>
+
+ * tc.const.c: Fixed bug in NTlamepathfix. Added variable
+ NTlameargfix. This will make it possible to run cmd or print
+ etc. without aliasing them.
+
+Rev 3.30
+Mon Sep 22 14:52:50 1997 <amold@SKYNYRD>
+
+ * ntport\support.c: Added wrapper for chdir, to convert
+ '/'s to '\'s on Win95.
+
+Rev 3.29
+Mon Sep 15 08:52:11 1997 <amold@SKYNYRD>
+
+ * ntport\bogus.c: Fixed bug in ~-expansion. ~foo was being expanded
+ to $home for the current user.
+ * sh.func.c: Changed isbfunc to use StrQcmp instead of my own
+ hacked unqoute_Strcmp.
+
+Rev 3.281
+Fri Sep 05 15:13:18 1997 <amold@SKYNYRD>
+
+ * ntport\ntfunc.c: Fixed stupid bug in unsetenv. Instead of
+ unsetting, a garbage value was being filled in.
+
+Rev 3.27
+Wed Aug 27 19:23:49 1997 <amold@SALEMS_LOT>
+
+ * sh.func.c: Fix for quoting aliased builtins. Thanks to
+ Vincent Fatica for pointing this bug out. It exists with
+ the unix version of tcsh 6.07.02 as well.
+
+Rev 3.262,Rev 3.263
+Tue Aug 26 17:33:38 1997 <amold@SKYNYRD>
+
+ * support.c: Fixed HOSTTYPE string to show NT service packs.
+ * sh.c: Fix for win95's lameness in parsing c://.tcshrc
+ If you really want to set a silly home directory like
+ C:/, it should work now.
+
+Rev 3.26, 3.261
+Mon Aug 18 17:53:25 1997 <amold@SKYNYRD>
+
+ * sh.dol.c: Fix for echoing input when using $< interactively
+ * sh.exec.c: Fix for completing directory names properly. For
+ example, c:/b<tab> will list directories as well as executables.
+
+Rev 3.25
+Thu Aug 07 07:47:07 1997 <amold@SKYNYRD>
+
+ * sh.exec.c,ntport\ntfunc.c: Added hack to run .cmd or
+ .bat files. If they are hashed, they shall be run.
+
+Rev 3.24
+Wed Aug 06 17:36:50 1997 <amold@SKYNYRD>
+
+ * sh.exec.c: Fix for which/where on Win95
+
+Rev 3.232
+Wed Aug 06 14:21:01 1997 <amold@SKYNYRD>
+
+ * ntport\support.c: Fix for fix for dirs with spaces in path.
+
+Rev 3.23
+Thu Jul 31 11:43:56 1997 <amold@SKYNYRD>
+
+ * sh.lex.c,tc.func.c,ntport\io.c: Major code change. CRLF
+ translation was messing up loops in scripts. The shell would
+ seek to the wrong offset. Thanks to Rickard Westman for
+ isolating the problem. The file i/o routines now do no translation.
+ Everything is done in the shell code itself. This may lead to
+ unforseen bugs, so beware.
+
+Rev 3.22
+Mon Jul 28 07:58:24 1997 <amold@SKYNYRD>
+
+ * ed.chared.c: Fix for ^C aborting current input
+ * ntport\ntfunc.c: Make 'start' print error message if
+ command is not found.
+
+Rev 3.21
+Thu Jul 24 08:50:52 1997 <amold@SKYNYRD>
+
+ * ntport\support.c: fix for directories with space in $path
+
+Rev 3.20
+Thu Jul 17 09:59:32 1997 <amold@SKYNYRD>
+
+ * ntport\console.c: Fix for scroll messing up dislay
+
+Rev 3.19
+Wed Jul 09 14:20:30 1997 <amold@SKYNYRD>
+
+ * ntport\ntfunc.c: changed 'start' to only use '-' for switches
+ * ntport\ntfunc.c: added 'cls' builtin. The normal clear-screen function
+ has been fixed to clear only the visible window. Use cls if you need
+ to clear the entire buffer.
+
+Rev 3.18
+Fri Jun 27 14:08:40 1997 <amold@SKYNYRD>
+
+ * ntport\support.c,tc.const.c : Added variable NTlamepathfix, which
+ when set will replace '/' in the PATH with '\' for child processes. Also
+ works with the start builtin.
+
+Rev 3.17
+Tue Jun 24 17:51:17 1997 <amold@SKYNYRD>
+
+ * ntport\nt.who.c: Fix for crashes on exit in win95.
+
+Rev 3.16
+Fri Jun 20 08:28:58 1997 <amold@SKYNYRD>
+
+ * ntport\ntfunc.c: Fix for env variable fix. Also other misc memory
+ cleanup things. Env variables greater than 1024 now CANNOT be set.
+
+Rev 3.15
+Mon Jun 16 19:55:00 1997 <amold@SALEMS_LOT>
+
+ * ntport\ntfunc.c: Fixed buffer overrun problems in nt_set_env.
+ Environment variables will now be truncated at 1024 bytes.
+ * sh.proc.,ntport\support.c: nohup foo & now creates a detached process.
+ This child has no access to the parent's console, and will continue to run
+ if the parent shell exits and the console goes away.
+
+Rev 3.14
+Fri Jun 13 08:54:53 1997 <amold@SKYNYRD>
+
+ * dirent.c, signal.c, io.c: minor bugfixes for dirent. Major
+ fixes for sigint handling.
+
+Rev 3.12
+Sun Jun 08 13:57:16 1997 <amold@SKYNYRD>
+
+ * ntport\nt.who.c, tc.who.c: Added support for watch(). Needs
+ more testing.
+
+Rev 3.11
+Thu Jun 05 16:33:01 1997 <amold@SKYNYRD>
+
+ * ntport\ntfunc.c: added new variable 'oldtitle'. stores the
+ previous value of title, every time the title builtin is used.
+
+Rev 3.10
+Wed May 28 13:47:44 1997 <amold@SKYNYRD>
+
+ * ntport\dirent.c: Enhancements for cd //server/<tab> or
+ ls //server. Basically, enumerate shares as if they were files.
+ May not work if the server is win95, but I don't give a damn
+ about that.
+
+Rev 3.09
+Thu May 22 08:31:19 1997 <amold@SKYNYRD>
+
+ * tw.parse.c: Support for complete=igncase. Like enhance, but
+ restricted to case-insensitive completion.
+
+Rev 3.08
+Mon May 19 11:54:22 1997 <amold@SKYNYRD>
+
+ * ntport\io.c: Fix for file descriptor confusion in non-interactive
+ shell.(Manifested as hangs in emacs compilation, for example)
+
+Rev 3.07
+Sat May 17 15:12:24 1997 <amold@SKYNYRD>
+
+ * tc.func.c: Fixes to hashbang for #!c:/bin/tcsh.exe<space>
+
+Rev 3.06
+Thu May 15 08:37:47 1997 <amold@SKYNYRD>
+
+ * ntport\io.c: Fix for heinous append(or lack thereof) redirection
+ bug.
+
+Rev 3.06
+Mon May 12 16:19:42 1997 <amold@SKYNYRD>
+
+ * tc.prompt.c: Fix to print drive letter with %c prompt format
+
+Rev 3.05
+Thu May 08 17:54:12 1997 <amold@SKYNYRD>
+
+ * ntport\ntfunc.c: Restored 'title' builtin
+
+Rev 3.04
+Wed May 07 14:02:32 1997 <amold@SKYNYRD>
+
+ * sh.c: Fixed comparison with argv[0] for %c prompt format
+
+Rev 3.03
+Tue Apr 29 15:48:15 1997 <amold@SKYNYRD>
+
+ * sh.sem.c: Really fixed cd this time.
+
+Rev 3.02
+Fri Apr 25 07:51:26 1997 <amold@SKYNYRD>
+
+ * sh.sem.c: Fix for C: changing drives when implicitcd is set
+
+Rev 3.01
+Sat Apr 19 16:00:23 1997 amold <amold@SALEMS_LOT>
+
+ * ntport\io.c: Fixed heredoc temp files to be deleted on close.
+
+Rev 3.0
+Thu Apr 17 09:24:46 1997 <amold@SKYNYRD>
+
+ * ntport\io.c, ntport\fork.c: Fixes for compiling with optimization
+ turned on. This is a release version. I've named it 3.0 to
+ differentiate it from the 6.06.02 nt-rev-2.10 junk.
+
+Rev 1.9-beta
+Mon Apr 14 19:26:01 1997 amold <amold@SALEMS_LOT>
+
+ * sh.dol.c: Hacks to fix here documents. (cat <<EOF)
+
+Rev 1.8-beta
+Mon Apr 14 15:27:24 1997 <amold@SKYNYRD>
+
+ * ntport\signal.c: Put in a hack to avoid bad longjmps when ^C is hit.
+ (showed up as a 0xC00000029 exception)
+
+Rev 1.7-beta
+Fri Apr 11 07:43:39 1997 <amold@SKYNYRD>
+
+ * sh.proc.c: Fix for shell hanging on win95, after running command.
+
+Rev 1.6-Beta
+Thu Apr 10 19:56:57 1997 amold <amold@SALEMS_LOT>
+
+ * tw.parse.c: Fix to recognize C: when doing ls-F
+
+Rev 1.5-Beta
+Wed Apr 09 22:05:51 1997 amold <amold@SALEMS_LOT>
+
+ * ntport\signal.c: fixes for sched builtin. rearchitectured alarm()
+
+Rev 1.4 Beta
+Wed Apr 09 09:24:58 1997 <amold@SKYNYRD>
+
+ * ed.refresh.c: Edit-time refreshing fix from prev. tcsh
+
+Rev 1.3-Beta
+Tue Apr 08 21:02:14 1997 amold <amold@SALEMS_LOT>
+
+ * sh.exec.c, ntport\support.c: Fixed exec builtin.
+
+Rev 1.2-Beta
+Tue Apr 08 19:54:29 1997 amold <amold@SALEMS_LOT>
+
+ * sh.c: Fixed importpath to convert '\' to '/'. This fixes the where
+ builtin
+
+Rev 1.1-Beta
+Tue Apr 08 08:42:11 1997 <amold@SKYNYRD>
+
+ * sh.func.c: Fixed inheritance of environment variables.
+
diff --git a/win32/Contributors b/win32/Contributors
new file mode 100644
index 000000000000..8ccc71bad284
--- /dev/null
+++ b/win32/Contributors
@@ -0,0 +1,15 @@
+People who have contributed to tcsh for win32 with bugfixes, functionality,
+and other useful pieces of code. If I've left you out, please let me know !
+
+(In alphabetical order)
+
+Tom Kludy (tom.kludy@citrix.com)
+Yarek Kowalik (Yarek.Kowalik@Sitraka.com)
+Edward Lam
+Matt Landau
+Avner Lottem (avner.lottem@intel.com)
+blucas (?) (blucas@broadcom.com)
+Chun-Pong Yu (bol.pacific.net.sg)
+TAGA nayuta (nayuta@is.s.u-tokyo.ac.jp)
+Mike Thomas (miketh@brisbane.paradigmgeo.com)
+Mark Tucker (mtucker@fiji.sidefx.com)
diff --git a/win32/Makefile.win32 b/win32/Makefile.win32
new file mode 100644
index 000000000000..cddec24f185f
--- /dev/null
+++ b/win32/Makefile.win32
@@ -0,0 +1,285 @@
+# $Id: Makefile.win32,v 1.15 2010/05/24 22:19:26 amold Exp $
+# Makefile.std 4.3 6/11/83
+#
+# C Shell with process control; VM/UNIX VAX Makefile
+# Bill Joy UC Berkeley; Jim Kulp IIASA, Austria
+#
+# With an input editor, command completion, etc. and ported to all sorts of
+# things; Paul Placeway, CIS Dept., Ohio State University
+#
+#
+# Windows NT version: Amol Deshpande, Microsoft Corp.
+#
+
+################################################################
+## CFLAGS. For various -D things, see config.h
+################################################################
+#
+# These are the default suffixes from .c to .o and -c to get there
+# but to use the global optimizer on the mips boxes, see below
+#
+SUF=obj
+CF=-c -nologo
+
+INCLUDES=-I. -I.. -Iwin32
+
+DEBUG_CRTLIBS= libcmtd.lib oldnames.lib libcpmtd.lib
+CRTLIBS= libcmt.lib oldnames.lib libcpmt.lib
+
+EXTRAFLAGS = -DWINNT_NATIVE -DNO_CRYPT -DHAVE_DIRENT_H $(EFL)
+WINDOWS_WARNING_LEVEL=-W4 -WX
+REST_WARNING_LEVEL=-WX -W3
+ANALYZE_FLAGS = -analyze
+
+
+!if "$(PROCESSOR_ARCHITECTURE)" == "AMD64"
+#main code is broken for 64-bit. ignore warnings and pray it works
+
+REST_WARNING_LEVEL= -W3
+ANALYZE_FLAGS=
+IGNORE_64= -wd4244 -wd4267
+
+!if "$(WIN64)" == ""
+!Message
+!Message Assuming x64 compile. pass WIN64=0 in command line if compiling 32-bit
+!Message
+WIN64=1
+!endif
+
+!endif
+
+
+!if "$(WIN64)" == ""
+WIN64=0
+ARCH=x86
+!else
+ARCH=x64
+WIN64=1
+!endif
+
+BUILD=tcsh-$(ARCH).exe
+
+!if "$(BLDTYPE)" == ""
+BLDTYPE=retail
+!endif
+
+!if "$(BLDTYPE)" == "debug"
+
+
+NTLDFLAGS= -entry:silly_entry -debug
+NTCFLAGS = -Zi -DNTDBG -Od
+LIBES= user32.lib advapi32.lib kernel32.lib $(DEBUG_CRTLIBS) strsafe.lib
+
+!else if "$(BLDTYPE)" == "retail"
+
+NTLDFLAGS= -entry:silly_entry -debug
+NTCFLAGS = -Zi -O2
+LIBES= user32.lib advapi32.lib kernel32.lib $(CRTLIBS) strsafe.lib
+
+!else
+
+!ERROR Unknown compilation mode $(BLDTYPE). Set debug or retail
+!endif
+
+!if "$(WIN64)" == "1"
+NTCFLAGS = $(NTCFLAGS) -Zp8
+!endif
+
+CFLAGS= -MT $(NTCFLAGS) $(INCLUDES)
+LDFLAGS= -nodefaultlib $(NTLDFLAGS) -stack:1048576,524288
+
+
+CC= cl
+
+ED= ed
+RM= -del
+#
+# Resources. which icon you want to use.
+NTRES = BSDLOGO
+
+ASSRCS= sh.c sh.dir.c sh.dol.c sh.err.c sh.exec.c sh.char.c \
+ sh.exp.c sh.file.c sh.func.c sh.glob.c sh.hist.c sh.init.c \
+ sh.lex.c sh.misc.c sh.parse.c sh.print.c sh.proc.c sh.sem.c \
+ sh.set.c sh.time.c sh.char.h sh.dir.h sh.proc.h sh.h
+PSSRCS= sh.decls.h glob.c glob.h mi.termios.c mi.wait.h mi.varargs.h ma.setp.c \
+ vms.termcap.c
+SHSRCS= $(ASSRCS) $(PSSRCS)
+SHOBJS= sh.$(SUF) sh.dir.$(SUF) sh.dol.$(SUF) sh.err.$(SUF) sh.exec.$(SUF) \
+ sh.char.$(SUF) sh.exp.$(SUF) sh.func.$(SUF) sh.glob.$(SUF) \
+ sh.hist.$(SUF) sh.init.$(SUF) sh.lex.$(SUF) sh.misc.$(SUF) \
+ sh.parse.$(SUF) sh.print.$(SUF) sh.proc.$(SUF) sh.sem.$(SUF) \
+ sh.set.$(SUF) sh.time.$(SUF) glob.$(SUF) mi.termios.$(SUF) \
+ ma.setp.$(SUF)
+
+TWSRCS= tw.decls.h tw.h tw.help.c tw.init.c tw.parse.c tw.spell.c \
+ tw.comp.c tw.color.c
+TWOBJS= tw.help.$(SUF) tw.init.$(SUF) tw.parse.$(SUF) tw.spell.$(SUF) \
+ tw.comp.$(SUF) tw.color.$(SUF)
+
+EDSRCS= ed.chared.c ed.decls.h ed.defns.c ed.h ed.init.c ed.inputl.c \
+ ed.refresh.c ed.xmap.c ed.term.c ed.term.h
+EDOBJS= ed.chared.$(SUF) ed.refresh.$(SUF) ed.init.$(SUF) \
+ ed.inputl.$(SUF) ed.defns.$(SUF) ed.xmap.$(SUF) ed.term.$(SUF)
+
+TCSRCS= tc.alloc.c tc.bind.c tc.const.c tc.decls.h tc.disc.c \
+ tc.func.c tc.os.c tc.os.h tc.printf.c tc.prompt.c tc.nsl.c \
+ tc.sched.c tc.sig.c tc.sig.h tc.str.c sh.types.h tc.vers.c tc.wait.h \
+ tc.who.c tc.h
+TCOBJS= tc.alloc.$(SUF) tc.bind.$(SUF) tc.const.$(SUF) \
+ tc.disc.$(SUF) tc.func.$(SUF) tc.os.$(SUF) tc.printf.$(SUF) tc.nls.$(SUF) \
+ tc.prompt.$(SUF) tc.sched.$(SUF) tc.sig.$(SUF) tc.str.$(SUF) \
+ tc.vers.$(SUF) tc.who.$(SUF)
+
+NTSRCS = win32\io.c win32\stdio.c win32\dirent.c win32\signal.c\
+ win32\support.c \
+ win32\nt.char.c win32\bogus.c win32\console.c win32\fork.c \
+ win32\ntfunc.c win32\ntb1.c win32\ntb2.c win32\globals.c \
+ win32\nt.who.c win32\ps.c win32\clip.c win32\nt.const.c \
+ win32\nt.bind.c win32\nt.screen.c
+NTOBJS = io.$(SUF) stdio.$(SUF) dirent.$(SUF) signal.$(SUF) support.$(SUF) \
+ nt.char.$(SUF) bogus.$(SUF) console.$(SUF) fork.$(SUF) ntfunc.$(SUF) \
+ globals.$(SUF) nt.who.$(SUF) ps.$(SUF) \
+ clip.$(SUF) nt.const.$(SUF) nt.bind.$(SUF) nt.screen.$(SUF)
+
+VHSRCS=$(PVSRCS) $(AVSRCS)
+
+
+ALLSRCS= $(SHSRCS) $(TWSRCS) $(EDSRCS) $(TCSRCS) $(VHSRCS) $(NTSRCS)
+DISTSRCS= $(PSSRCS) $(TWSRCS) $(EDSRCS) $(TCSRCS) $(AVSRCS)
+
+
+OBJS= $(SHOBJS) $(TWOBJS) $(EDOBJS) $(TCOBJS) $(NTOBJS)
+
+
+all: $(BUILD)
+
+$(BUILD): $(OBJS) ntb1.$(SUF) ntb2.$(SUF) win32/$(NTRES).res
+ link $(LDFLAGS) ntb1.$(SUF) $(OBJS) $(LIBES) ntb2.$(SUF) $(EXTRALIBS) \
+ win32/$(NTRES).res $(LOADABLE_RES) -map:tcsh.map -out:$(BUILD)
+
+gcompress:$(BUILD)
+ gzip -v9 $(BUILD)
+
+bintar: gcompress
+ tar -cvf tcsh-$(ARCH)-bin.tar $(BUILD) win32/README.NT \
+ win32/example.tcshrc win32/tcsh-html.tgz win32/bin
+ gzip -v9 tcsh-$(ARCH)-bin.tar
+ move tcsh-$(ARCH)-bin.tar.gz ..
+
+win32srctar: $(NTSRCS)
+ tar -cvf tcshwin32src.tar win32 --exclude win32/bin
+ gzip -v9 tcshwin32src.tar
+ move tcshwin32src.tar.gz ..
+
+
+chlog:
+ tcsh -fc "echo \<XMP\> > win32\\Changelog.html"
+ type win32\Changelog >> win32\ChangeLog.html
+ tcsh -fc "echo \</XMP\> >> win32\\ChangeLog.html"
+
+
+
+.c.$(SUF):
+ $(CC) $(CF) $(CFLAGS) $(REST_WARNING_LEVEL) $(DFLAGS) $(EXTRAFLAGS) $<
+
+
+ed.defns.h: ed.defns.c
+ -@del $@
+ @echo /* Do not edit this file, make creates it. */ > $@
+ @echo #ifndef _h_ed_defns >> $@
+ @echo #define _h_ed_defns >> $@
+ findstr /R [FV]_ ed.defns.c | findstr /B #define >> $@
+ @echo #endif /* _h_ed_defns */ >> $@
+
+sh.err.h: sh.err.c
+ -@del $@
+ @echo /* Do not edit this file, make creates it. */ > $@
+ @echo #ifndef _h_sh_err >> $@
+ @echo #define _h_sh_err >> $@
+ findstr ERR_ sh.err.c | findstr /B #define >> $@
+ @echo #endif /* _h_sh_err */ >> $@
+
+tc.const.h: tc.const.c sh.char.h config.h config_f.h sh.types.h sh.err.h
+ -@del $@
+ @echo /* Do not edit this file, make creates it. */ > $@
+ @echo #ifndef _h_tc_const >> $@
+ @echo #define _h_tc_const >> $@
+ @for /f "tokens=1 delims==" %i in ('$(CC) -E $(INCLUDES) $(DFLAGS) $(EXTRAFLAGS) -D_h_tc_const -nologo \
+ tc.const.c ^| findstr /c:"Char STR" ^| sort') do @echo extern %i; >> $@
+ @echo #endif /* _h_tc_const */ >> $@
+
+win32\nt.const.h: win32\nt.const.c sh.char.h config.h config_f.h sh.types.h sh.err.h tc.const.h
+ -@del $@
+ @echo /* Do not edit this file, make creates it. */ > $@
+ @echo #ifndef _h_nt_const >> $@
+ @echo #define _h_nt_const >> $@
+ @for /f "tokens=1 delims==" %i in ('$(CC) -E $(INCLUDES) $(DFLAGS) $(EXTRAFLAGS) -D_h_nt_const -nologo \
+ win32\nt.const.c ^| findstr /c:"Char STR" ^| sort') do @echo extern %i; >> $@
+ @echo #endif /* _h_nt_const */ >> $@
+
+clean:
+ $(RM) *.$(SUF) sh.prof.c ed.defns.h tc.const.h sh.err.h tc.defs.c
+ $(RM) *.pdb *.pch *.ilk *.map *.dbg *.res
+ cd win32
+ $(RM) *.res nt.const.h
+ cd ..
+
+cleanall: clean
+ -del $(BUILD)
+
+
+config.h: config_f.h
+
+TCH=tc.h tc.const.h tc.decls.h tc.os.h tc.sig.h
+SHH=sh.h sh.types.h sh.char.h sh.err.h sh.dir.h sh.proc.h pathnames.h \
+ sh.decls.h $(TCH)
+TWH=tw.h tw.decls.h
+EDH=ed.h ed.decls.h
+
+# EDH
+EDINC=sh.$(SUF) sh.func.$(SUF) sh.lex.$(SUF) sh.print.$(SUF) sh.proc.$(SUF) \
+ sh.set.$(SUF) tc.bind.$(SUF) tc.os.$(SUF) tc.prompt.$(SUF) \
+ tc.sched.$(SUF) tw.parse.$(SUF)
+$(EDOBJS) $(EDINC) : $(EDH)
+
+# SHH
+$(OBJS): win32\nt.const.h win32\ntport.h win32\version.h config.h $(SHH)
+
+# TWH
+TWINC=ed.chared.$(SUF) ed.inputl.$(SUF) sh.exec.$(SUF) sh.func.$(SUF) \
+ sh.set.$(SUF) tc.func.$(SUF)
+$(TWOBJS) $(TWINC): $(TWH)
+
+# glob.h
+glob.$(SUF) sh.glob.$(SUF): glob.h
+
+# ed.defns.h
+EDDINC=tc.bind.$(SUF) tc.func.$(SUF) tc.os.$(SUF)
+$(EDOBJS) $(EDDINC): ed.defns.h
+
+# tc.defs.o
+tc.defs.$(SUF): tc.defs.c sh.h
+
+# too many 64-bit warnings in these files. for now, turn the warning off.
+ed.chared.$(SUF): ed.chared.c
+ $(CC) $(CF) $(CFLAGS) $(DFLAGS) $(EXTRAFLAGS) $(IGNORE_64) ed.chared.c
+ed.inputl.$(SUF): ed.inputl.c
+ $(CC) $(CF) $(CFLAGS) $(DFLAGS) $(EXTRAFLAGS) $(IGNORE_64) ed.inputl.c
+
+#
+# NT dependencies and rules
+#
+CFLAGS_WX = $(CFLAGS) $(WINDOWS_WARNING_LEVEL) -DWINDOWS_ONLY $(ANALYZE_FLAGS)
+
+{win32}.c.$(SUF):
+ $(CC) $(CF) $(CFLAGS_WX) $(DFLAGS) $(EXTRAFLAGS) $<
+
+fork.$(SUF):win32\fork.c
+ $(CC) $(CF) $(CFLAGS_WX) $(DFLAGS) $(EXTRAFLAGS) -GS- win32\fork.c
+
+nt.bind.$(SUF):win32\nt.bind.c ed.defns.h
+
+nt.screen.$(SUF):win32\nt.screen.c ed.defns.h
+
+win32/$(NTRES).res: win32/$(NTRES).rc win32/tcshrc.rc
+ rc -v $(RCFLAGS_WX) -r win32/$(NTRES).rc
diff --git a/win32/README.NT b/win32/README.NT
new file mode 100644
index 000000000000..ab48e2548adc
--- /dev/null
+++ b/win32/README.NT
@@ -0,0 +1,605 @@
+tcsh Windows NT version
+-----------------------
+
+You can get current binaries for this version of tcsh from
+ftp.blarg.net:users/amol/tcsh.
+
+--------------------------------------------------------------------------
+NT sources for tcsh can be now found in the same place as
+the unix tcsh sources, via anonymous ftp from ftp.astron.com.
+The location is /pub/tcsh.
+
+Files to get:
+
+tcsh-6.xx.tar.gz - Basic Unix source
+tcsh-6.xxwin32src.tar.gz - Extracts into "win32" subdirectory of basic source.
+
+Pre-compiled binaries and html docs for Alpha and x86 can also be
+found in the same location.
+--------------------------------------------------------------------------
+
+Send comments/bug-fixes/questions to amol@blarg.net
+
+(Any requests to make tcsh more like DOS shells will be ignored. If you
+like DOS shells, use them. tcsh provides unix shell behaviour on windows,
+not the other way around.)
+
+Please do not ask me general shell questions either. If you've never
+used a unix shell, read the man pages and docs. Read the comp.unix.shell
+FAQ.
+
+Bug reports that do not contain your operating system type will
+also be ignored.
+
+Bug reports that can be solved by reading the docs or README.NT will be
+ignored as well.
+
+Microsoft Corporation has nothing to do with this code. It is not supported in
+any fashion by Microsoft.
+
+-----------------------------------------------------------------------------
+This is NOT a Cygwin gcc version. It will not compile with Cygwin gcc or
+work seamlessly with Cygwin apps. Do NOT ask me to hack support for Cygwin
+'mount points' unless you are willing to provide the translation code.
+
+To prevent Cygwin applications from expanding wildcards, set the environment
+variable CYGWIN to "noglob". i.e., in your .tcshrc, put a line like this:
+
+setenv CYGWIN noglob
+
+(Cygwin applications assume that if they are not started from a shell
+using the Cygwin runtime, the parent shell does not have the ability to glob.
+This is visible as tcsh apparently expanding wildcards for quoted arguments.)
+
+-----------------------------------------------------------------------------
+
+All paths MUST be '/'-delimited. Do not expect the shell to work with
+DOS-style paths.
+
+
+Compiling:
+---------
+You will need sed to generate some headers.
+
+You must extract the win32src.tar.gz into a subdirectory of the basic
+unix source.
+
+tcsh currently only compiles with Microsoft Visual C++ (2.0 and greater) on
+x86 or Alpha platforms. Simply copy config/win32 to config.h and
+win32/makefile.win32 to the base directory.
+
+run nmake -f makefile.win32
+
+If you plan to contribute changes, PLEASE read the file CODING
+
+(Note: This distribution does not have a VC project. To compile the shell,
+you will need to open a cmd.exe/command.com window, run vcvars32.bat from
+your VC bin subdirectory and then run nmake as above).
+
+
+
+Known Bugs:
+----------
+* Horizontal scrolling is completely busted.
+* The 'time' builtin does not work.
+
+* There is a hard limit of 64Kb on the size of the command line. This is
+ an os-specific limit and cannot be changed.
+
+* Launching applications via explorer associations is slow if the argument
+ list is large.
+
+-----------------------------------------------------------------------------
+* This section only documents features specific to Windows NT/95 or
+* behaviour that is different from the Unix version. For complete tcsh
+* documentation, please read the man pages or html docs.
+-----------------------------------------------------------------------------
+
+Version numbers below refer to the tail end of the $version variable,
+containing the NT-specific version. For example,
+
+tcsh 6.09.00 (Astron) 1999-08-16 (i586-Microsoft-Windows2000) options 8b,nls,dl,hb,color,nt-rev-5.40
+
+In this case, the NT-specific version is 5.40
+
+
+Environment Variables:
+---------------------
+Environment variables are case-insensitive on NT. tcsh as of 5.33 has
+also been changed to reflect this behaviour. Thus,
+
+setenv FOO bar
+
+and,
+
+setenv foo bar
+
+are equivalent.
+
+Note that the *value* is, of course, not case-insensitive.
+
+
+Features
+--------
+
+* No backgrounding/job control. Use 'start' instead
+
+ You can also use
+ <foo> &
+ or,
+ nohup <foo> &
+
+ where <foo> is some arbitrary command.
+
+DO NOT start console apps with & unless u want them to read/write to your
+console. (A "console app" is any 32-bit application that is not GUI based.)
+
+(nohup foo & will say "foo Done" pretty quickly, but ignore that. There is no
+way for the shell to know when the nohupped process dies. Your job may still
+be running in the background.)
+
+* Filenames in the directories under WINNT (or WINDOWS or whatever you call
+ your windows directory) are hashed only if they are .EXE.
+ Names which are uppercase (For example, CALC.EXE) will also be hashed as
+ lowercase,without extension. Thus, "where calc" as well as
+ "where CALC.EXE" will work.
+
+(Explanation: tcsh uses a hashtable to track the location of executables. By
+default on Unix, all the files in every path element are hashed. Since the
+SystemRoot on NT has hundreds of junk files, tcsh will only hash .EXE files.
+This hashing is, of course, case-sensitive. Thus CALC.EXE hashes to a
+different value than calc.exe would. To enable the shell to work in a Windows
+environment, tcsh will hash CALC.EXE as CALC.EXE as well as "calc").
+
+
+Special Variables
+-----------------
+* The tcsh "complete" variable can be set to igncase and will cause the shell
+ to ignore case in completion. This is slightly different from
+ the behaviour of complete=enhance, which should still work as before.
+
+* oldtitle:
+
+ Stores the previous value of the console title, when you use
+ the title builtin below. Use it like so:
+
+ title "$oldtitle"
+
+ to restore the previous title.
+
+* NTlamepathfix:
+
+ When set, '/'-s in the PATH environment variable will be
+ changed to '\'. This helps applications started within tcsh that may
+ not handle Unix-style PATHs.
+
+* NTslowexec:
+
+ When set, this variable disables attempts to save a fork() by
+ directly executing simple commands. "Simple" command means one which is
+ interactive and not piped, niced, nohupped etc. redirecting output of
+ a command also disables this optimization.
+
+ Since this shortcut feature is new, the variable provides a way to retain
+ backward compatibility. It may be taken out at some time in the future, if
+ the shell is found to be stable enough.
+
+ If you see problems like the shell seeming to expand wildcards when it
+ shouldn't, or other substitutions which should be quoted, set this
+ variable and see if that fixes the problem.
+
+* NTnoquoteprotect:
+
+ Ordinarily , if you pass a double quote to a command string, tcsh
+ will protect the quotes by adding backslashes. For example,
+
+ find . -name '"*.c"'
+ would get executed as
+
+ find . -name \"*.c\"
+
+ Some applications (MKS find, for example) do not like the '\'. To
+ prevent tcsh from quoting such arguments, set this variable.
+
+ Of course, it may cause other applications to break, so use at
+ your own risk.
+
+* NTcaseifypwd:
+
+ If set, corrects case of current directory when cd'ing into it. Apparently,
+ some "filesystems" can't handle the default behaviour. Only works on
+ Windows NT.
+
+* TCSHSUBSTHB (Environment, NOT shell variable):
+
+ Specifies mappings for hashbang emulation. Should be ';'-separated pairs
+ of blank-separated mappings.
+
+ For example,
+
+ setenv TCSHSUBSTHB "/usr/local/bin/perl c:/bin/perl.exe;"
+
+ will substitute #!c:/bin/perl.exe for scripts which have
+ #!/usr/local/bin/perl at the top.
+
+ The final ';' MUST be included. I don't check for errors too
+ carefully, so it's up to you to supply the exact sequence.
+ There is a hardcoded limit of 20 such pairs.
+
+
+* TCSHONLYSTARTEXES (Environment variable):
+
+ Can be set on the fly and controls whether associations will be tried
+ for non-executables.
+
+ ("Associations" here means Explorer file-type associations, that cause,
+ for example, Microsoft Word to be launched when you type "foo.doc" at
+ a command prompt. That can have unexpected side-effects like batch files
+ and perl scripts launching in another window when run from tcsh. )
+
+ Any changes to this variable will NOT affect the the "start" builtin.
+ This builtin ALWAYS launches associations, since the whole point of
+ using "start" is to not block the current shell.
+
+ You can also supply a semi-colon-separated list of extensions for
+ which to NOT try associations. For example, if the variable is set to
+
+ "cmd;bat",
+
+ .cmd/.bat files will be executed in the same window because the default
+ association is not used, instead an internal hack feeds them to the
+ DOS command processor.
+
+ If the file extension does not match the list, the shell will try to
+ launch an association.
+
+ o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-
+
+ To achieve the old behaviour of this setting, you must set the
+ variable to a 1-character value.i.e.,
+
+ setenv TCSHONLYSTARTEXES
+
+ should be replaced by
+
+ setenv TCSHONLYSTARTEXES 1
+
+ This setting, as before, will prevent tcsh from trying associations
+ for ANY non-executable.
+
+ (a zero-length setting will not work. A length greater than 1 will
+ be assumed to be a list of extensions as above.)
+
+ o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-
+
+
+
+* TCSH_NOASYNCGUI (Enviroment variable):
+
+ Makes tcsh wait for win32 GUI apps to terminate, instead of returning
+ immediately. This affects child processes, so it can be set/unset in
+ the parent shell at any point.
+
+
+NT-specific Builtins
+--------------------
+* start: like cmd.exe's start
+* title: change the shell title
+* cls: Clear the entire console buffer instead of just the visible window.
+* ps: list processes running currently. With -w, list window titles as well.
+
+* shutdown: (works on Windows NT only)
+
+ shutdown -[r|l|f] now
+
+(Even though no time argument is supported, "now" must be specified, EXCEPT
+with -l .This is to prevent you from accidentally shutting the machine down.)
+ -r reboots, -l logs you off and -f forces apps to terminate.
+
+The default action is to shut the machine down.
+
+
+* sourcerc: tcsh can be compiled with a stringtable resource that can be
+ sourced using this command. This feature is designed as a way to avoid
+ having to copy the .tcshrc to every computer you run tcsh on. The default
+ resource is a simple version of my .tcshrc. More complicated settings can
+ then be copied when needed.
+
+* printrc: print the compiled-in resource that will be sourced by sourcerc.
+
+
+Notes:
+-----
+* You should probably get the Cygwin utilities from http://cygwin.com
+
+ Things like 'ls' and 'cat' are useful, since we don't have a 'type' or 'dir'
+ anymore. 'ls' is pretty much a requirement unless you never do 'ls -l'.
+
+
+* tcsh was compiled with Visual C++ >= 4.2. I don't guarantee it will compile
+ with any other compilers, but it should. It will *not* compile with the
+ Cygwin gcc port, so don't even tell me about it.
+
+* It should be pointed out that there is also a Cygwin version of tcsh that
+ will compile with gcc and provide all the other features emulated by the
+ Cygwin runtime (like job control, signals, etc.). So, if you are looking for
+ a way to pretend that you are on Unix, you should use that version.
+ The same holds true for UWIN as well.
+
+
+Startup Files:
+--------------
+
+For Windows 95:
+ <windows_directory>/.tcshrc
+ For Example, C:\WINDOWS\.tcshrc
+
+For Windows NT:
+ version 3.51: <getenv(HOMEDRIVE)/getenv(HOMEPATH)/.tcshrc>
+ Usually something like C:\USERS\DEFAULT\.tcshrc
+
+ version 4.00: <getenv(USERPROFILE)/.tcshrc)
+ Usually something like C:\WINNT\USERS\amold\profile\.tcshrc
+
+These can all be overridden by setting HOME in the user's environment
+
+
+
+* TCSHLANG: NLS support
+
+You can get messages in a specific language by doing:
+
+ setenv TCSHLANG <dll>, where <dll> is the name of the NLS dll.
+
+tcsh comes with:
+
+ tcshde.dll -> German
+ tcshfr.dll -> French
+ tcshsp.dll -> Spanish
+ tcsh-it.dll -> Italian
+
+ tcshc.dll => Default "C" locale
+
+You can change the dll at runtime by setting/unsetting this variable.
+
+You can specify the DLL name, or the complete path, if it is not in your
+standard search path.
+
+(Using tcshc.dll is useless and adds unnecessary overhead. If you are
+using English versions, do not install the dlls)
+
+
+Virtual key code bindings:
+-------------------------
+To use keys like function keys, arrows, insert, etc., the following
+form of bindkey must be used:
+
+bindkey -b N-xxx <command>
+
+where xxx is either:
+ a) A number from 1 through 24, representing the fucntion keys.
+ For example, bindkey -b N-1 run-help
+
+ b) The strings "pgup","pgdown","end","home", "left","up","right","down",
+ "ins","del"
+ For example, bindkey -b N-del delete-char
+
+Here are the bindings I use in my .tcshrc:
+
+# NT specific bindkey extensions
+ bindkey -b N-up up-history
+ bindkey -b N-down down-history
+ bindkey -b N-right forward-char
+ bindkey -b N-left backward-char
+ bindkey -b N-del delete-char
+ bindkey -b N-ins overwrite-mode
+ bindkey -b N-1 which-command
+ bindkey -b N-2 expand-history
+ bindkey -b N-3 complete-word-raw
+ bindkey -b N-home beginning-of-line
+ bindkey -b N-end end-of-line
+
+ bindkey -b N-pgup e_page_up
+ bindkey -b N-pgdown e_page_down
+
+(Note that on Win9x, you must set your console window to NOT be Auto
+sized, and you must use the "settc" builtin to increase and then reduce
+back the number of lines, in order to get a scrollbar. pgup and
+pgdown will not work without a scroll bar)
+
+
+To bind ctrl or alt combinations, use the following as examples.
+
+ bindkey -b N-C-left backward-word
+ bindkey -b N-M-right forward-word
+
+For Shift combinations:
+ bindkey -b N-S-1 backward-word
+
+Clipboard support
+-----------------
+Since version 3.58, you can cut and paste to and from the clipboard
+directly from the shell. To do this, use bindings like the following:
+
+ bindkey -b M-x e_copy_to_clipboard
+ bindkey -b M-y e_paste_from_clipboard
+
+Then, to paste text from the clipboard into the current input line, you
+can type:
+ M-y
+And to copy the current shell's kill buffer to the clipboard,
+ M-x
+
+(The kill buffer contains the last deletion from an editing command. Sort
+of like an 'undo' buffer).
+
+You can also use the clipboard to redirect I/O, with /dev/clipboard as
+the destination/source file.
+
+
+NOTE: From version 6.00 onwards, the e_paste operation does NOT copy the
+clipboard contents to the shell kill buffer.
+
+
+
+e_dosify_next
+-------------
+A key bound to this editor function can be used to convert unix-style
+paths to DOS-style paths.
+For example,
+ bindkey -b M-/ e_dosify_next
+Then, if I had line like so:
+ xcopy /e /u c:/nt40/system32
+I would move the cursor to the C: and hit alt-/. magically, the command
+line changes to
+ xcopy /e /u c:\\nt40\\system32
+
+This function converts every '/' to '\\' until the first space. If the
+space is escaped by a '\', the function looks for the next space.
+
+e_dosify_prev
+-------------
+Works like above, but on the previous word. Matt Landau pointed out that
+this was much more convenient.
+
+e_page_up
+---------
+Editor function to move console window up one page. Can be bound to
+PageUp key.
+
+e_page_down
+----------
+Ditto for page down.
+
+
+Literal Prompt Characters
+-------------------------
+tcsh uses a special syntax for embedding literal character sequences in the
+prompt. For example, ANSI escapes.
+Thus, if you did
+set prompt='%{<ESC>[44mfoo%}\>',
+this will print the prompt in the appropriate colors.
+
+The color-ls patch in 6.07.09 implements parsing for ANSI escapes. To keep
+the prompt specification consistent with the availablity of this feature,
+the literal string will now accept ANSI escapes like color-ls would.
+
+The shell can be compiled for the old behaviour, but I don't recommend it.
+
+I'm aware this is a major incompatibility, but I think the change is
+worthwhile.
+
+As an example, here is my new prompt, with the old one as a reference.
+
+#old specification
+# set prompt='%{f9%}%c03%{gg%}\>'
+# set prompt3 = '%{fc%}Correct to %R ?(y|n|e)%{gg%} '
+
+# new spec.
+ set prompt='%{^[[1;34m%}%c03%{^[[0m%}\>'
+ set prompt3='%{^[[1;31m%}Correct to %R ?(y|n|e)%{^[[0m%} '
+#
+#
+
+ls-F is noticeably slow if color is set. This is especially true on slower
+machines (P100, for example). You may not want to set it for those kinds
+of systems. More so if you already have an external color-ls.
+
+watch:
+-----
+Since rev 3.12, support (ha ha) for the watch variable has been added. This
+will work only on a Microsoft Windows Network, i.e, where computers
+participate in an NT domain. Here is how tcsh will work if your network
+configuration is to its taste:
+
+ set watch=(2 AMOLD SKYNYRD any LYNYRD)
+
+sets a watch for AMOLD on machine SKYNYRD, and any user on machine LYNYRD. The
+watch interval is 2 minutes.
+
+Note that these are NETBIOS names, and hence the results may be flaky. There
+is no good way to distinguish computer names from user names in a netbios name
+table (even a good guess is very expensive), so be prepared for unexpected
+results.
+
+There may be problems depending on what protocol is on lana number 0.
+(This will usually be shown (and/or set) on NT in the properties for the
+NETBIOS interface in the control panel/networks applet. Win95 is screwed up,
+and if you have more than one protocol, watch may not work. Don't bug me
+about it)
+
+Also note that names must all be uppercase.
+
+The default time interval of 10 minutes is probably good, since you don't want
+to generate too much network traffic.
+
+Nice:
+-----
+//
+// nice(niceness)
+//
+// where niceness is an integer in the range -6 to +7
+//
+// A usual foreground process starts at level 9 in the chart below
+//
+// the range -6 to +7 takes it from Base priority 15 down to 2.
+//
+// Note that level 1 or > 15 are not allowed.
+//
+// Priority Level 11 (niceness -2) or greater affects system performance,
+// so use with care.
+//
+// niceness defaults to +4, which is lowest for background normal class.
+// As in unix, +ve niceness indicates lower priorities.
+
+/***************************************************************************
+Niceness Base Priority class/thread priority
+
+ 1 Idle, normal, or high class, THREAD_PRIORITY_IDLE
+
++7 2 Idle class, THREAD_PRIORITY_LOWEST
++6 3 Idle class, THREAD_PRIORITY_BELOW_NORMAL
++5 4 Idle class, THREAD_PRIORITY_NORMAL
++4 5 Background normal class, THREAD_PRIORITY_LOWEST
+ Idle class, THREAD_PRIORITY_ABOVE_NORMAL
++3 6 Background normal class, THREAD_PRIORITY_BELOW_NORMAL
+ Idle class, THREAD_PRIORITY_HIGHEST
++2 7 Foreground normal class, THREAD_PRIORITY_LOWEST
+ Background normal class, THREAD_PRIORITY_NORMAL
++1 8 Foreground normal class, THREAD_PRIORITY_BELOW_NORMAL
+ Background normal class, THREAD_PRIORITY_ABOVE_NORMAL
+ 0 9 Foreground normal class, THREAD_PRIORITY_NORMAL
+ Background normal class, THREAD_PRIORITY_HIGHEST
+-1 10 Foreground normal class, THREAD_PRIORITY_ABOVE_NORMAL
+-2 11 High class, THREAD_PRIORITY_LOWEST
+ Foreground normal class, THREAD_PRIORITY_HIGHEST
+-3 12 High class, THREAD_PRIORITY_BELOW_NORMAL
+-4 13 High class, THREAD_PRIORITY_NORMAL
+-5 14 High class, THREAD_PRIORITY_ABOVE_NORMAL
+-6 15 Idle, normal, or high class, THREAD_PRIORITY_TIME_CRITICAL
+ High class, THREAD_PRIORITY_HIGHEST
+
+
+ 16 Real-time class, THREAD_PRIORITY_IDLE
+ 22 Real-time class, THREAD_PRIORITY_LOWEST
+ 23 Real-time class, THREAD_PRIORITY_BELOW_NORMAL
+ 24 Real-time class, THREAD_PRIORITY_NORMAL
+ 25 Real-time class, THREAD_PRIORITY_ABOVE_NORMAL
+ 26 Real-time class, THREAD_PRIORITY_HIGHEST
+ 31 Real-time class, THREAD_PRIORITY_TIME_CRITICAL
+****************************************************************************/
+
+kill:
+----
+
+You can try to kill a process 4 ways:
+
+kill -1 <pid> (which will send a sigint)
+kill -2 <pid> (which will send a sigbreak)
+
+1 and 2 are only good for processes started in the same console. The
+signals cannot be sent to other process groups (other consoles/GUI apps).
+
+kill -3 <pid> (which will send a quit message to each window of the child>
+
+kill -7 <pid> , which will call TerminateProcess()
diff --git a/win32/WindowsReadme.1st b/win32/WindowsReadme.1st
new file mode 100644
index 000000000000..91ff88fddb23
--- /dev/null
+++ b/win32/WindowsReadme.1st
@@ -0,0 +1,556 @@
+This document applies to the Windows NT (including Windows 2000, XP, Server
+ 2003 etc.) native versions of tcsh.
+
+Note that the shell probably does work on Windows NT 4.0 or Windows 95, 98, and
+Me. However, making fixes solely for those operating systems is lowest on my
+priority list.
+
+"Windows NT" from here on refers to Windows 2000, XP etc. "Win 9x" means
+Windows 95,98 etc.
+
+
+I will attempt to describe the various differences between the Unix and the
+native Windows versions of tcsh. I assume at least a passing familiarity with
+Unix, Windows and tcsh.
+
+
+How to tell if you're running the native version (versus cygwin)
+----------------------------------------------------------------
+If,
+ - You built the binary from the tcsh distribution, using Visual C++.
+
+ Or, you downloaded it from www.blarg.net/~amol/~tcsh.exe.gz.
+
+ Or, you downloaded it from ftp.blarg.net:users/amol/tcsh.
+
+ Or, you type echo $version and see something like:
+
+ tcsh 6.12.01 (Astron) 2003-02-08 (i686-Microsoft-WindowsXP) options 8b,nls,dl,hb,color,nt-rev-7.03
+
+ (The string "nt-rev-N.NN" only exists on native binaries of
+ tcsh. The actual revision may be different, as it is a minor
+ revision of the tcsh major version (6.12.01 in this case).)
+
+ If none of the above is true, this document is not for you.
+
+
+Who do I bug about bugs ?
+-------------------------
+
+ If the bug is on the lines of "cmd.exe does this, but tcsh doesn't", you
+ have a very slim chance of having me look at it. If you feel strongly
+ enough, grab the source and hack away. Isn't that the joy of Open Source
+ (TM) ?
+
+
+ Also, try running the latest version if you can. Your bug may already be
+ fixed.
+
+ If you still want to report a bug:
+
+ First, verify if applicable/possible on a Unix system that the behaviour is
+ actually different.
+
+ Secondly, setenv CYGWIN noglob if it's not already set. If that still
+ doesn't work, then
+
+ Third,
+
+ set NTslowexec
+ setenv TCSHONLYSTARTEXES 1
+
+ and try to reproduce the problem.
+
+
+ Even if the 3rd step seems to fix the behaviour, you should still report the
+ bug to amol@blarg.net with the following information:
+
+ - The output of echo $version
+ - The version of the operating system ("Windows" is not good enough.)
+ - The output from "set" and "setenv"
+ - The exact steps to reproduce the problem.
+
+
+ Be prepared to be quizzed on the contents of this file.
+
+How do I compile the source ?
+-----------------------------
+ - Download and extract the source from ftp.astron.com. Say it creates a
+ directory called tcsh-6.12.01
+
+ - Open a cmd.exe prompt and cd into this directory. Run "vcvars32.bat" from
+ your Visual C++ installation.
+
+ - type "copy config\win32 config.h"
+
+ - type "nmake -f win32\makefile.win32"
+
+
+ You will need sed to generate some headers.
+
+
+
+Known bugs
+----------
+ The "time" builtin does not work.
+
+
+Startup Files:
+--------------
+
+tcsh will create a HOME variable, if none is set, based on the OS.
+
+For Win 9x:
+ <windows_directory>/.tcshrc
+ For Example, C:\WINDOWS\.tcshrc
+
+For Windows NT:
+ version 3.51: <getenv(HOMEDRIVE)/getenv(HOMEPATH)/.tcshrc>
+ Usually something like C:\USERS\DEFAULT\.tcshrc
+
+ version 4.00 and above: <getenv(USERPROFILE)/.tcshrc)
+
+ This can vary from something like C:\WINNT\USERS\amol\profile\.tcshrc
+ on NT 4.0 to C:\Documents And Settings\amol\.tcshrc on Windows 2000 and
+ higher.
+
+These can all be overridden by setting HOME in the user's environment before
+the shell is launched.
+
+To create a .tcshrc on Windows, you just need a real editor like Vim.
+
+
+
+o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o
+
+ Various differences from Unix, FAQs, etc.
+
+o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o
+
+
+This document is correct as of 6.12.01
+
+ New Builtins
+ ------------
+ * start : Works like cmd.exe's "start". Use to launch an application or
+ launch a filetype association.
+
+ Can also be used to launch Windows Explorer on a directory by
+ typing "start c:/foo", for example.
+
+ Also "start http://www.tcsh.org" will launch Internet explorer
+ with that URL.
+
+ ("Associations" here means Explorer file-type associations, that cause,
+ for example, Microsoft Word to be launched when you type "foo.doc" at
+ a cmd.exe prompt. That can have unexpected side-effects like batch files
+ and perl scripts launching in another window when run from tcsh. )
+
+ * title: Sets the title of the shell. Stores the current title in
+ $oldtitle before changing it.
+
+
+ * cls: Clear the entire console screen buffer instead of the visible
+ window.
+
+ * ps : List processes. With -w, list titles as well.
+
+
+ * shutdown [-r | -l | -f] now : Windows NT only. Reboot or log off. -f
+ forces open applications to close. "now" must be specified for reboots.
+
+
+ Builtins that behave differently
+ ------------------------------------
+This section documents the builtins that present on Unix as well as windows,
+but function slightly differently on Windows. Also mentioned is behaviour that
+is different from what you are used to on Windows.
+
+ * Backgrounding (launching commands with '&').
+
+ While this is possible, be aware that Windows does not have any job
+ control. Thus you cannot attempt to bring a backgrounded job into the
+ foreground with '%<job number>' as on Unix.
+
+ Also note that a background job will most likely be killed if you exit
+ the command prompt that launched it. To prevent this from happening,
+ use the "nohup" builtin. For example:
+
+ nohup foo &
+
+ This will print "foo Done" quickly, as if the job actually completed.
+ However, if you type "ps", you will see that foo is still running. The
+ shell does not know after nohup whether the child process is
+ running or not.
+
+ * Case insenstivity of environment variable names.
+
+ To maintain consistency with Windows, and avoid conflicts, the
+ following are equivalent on Windows:
+
+ setenv FOO bar
+
+ setenv foo bar
+
+ Note that setenv foo BAR and setenv foo bar ARE NOT the same. Thus if
+ some application is sensitive to the case of an environment variable's
+ VALUE, you should set it exactly as required.
+
+ * No termcap set/unset with settc/echotc/telltc.
+
+ The only capabilities controllable are lines and columns. For example,
+
+ settc co 80
+ settc li 50
+
+ similarly,
+
+ echotc cols
+ or
+ echotc lines
+
+ will echo the number of columns and lines respectively.
+
+ echotc buffer
+
+ will echo the size of the console screen buffer.
+
+
+ Note that settc has an interesting side effect, which was left in
+ because it can be useful. Consider the following:
+
+ If your original line size was 50, with a console screen buffer of 50
+ as well (no scrollback), then typing
+
+ settc li 300
+
+ followed by
+
+ settc li 50
+
+
+ has the effect of setting your console screen buffer to 300, so you
+ now have a scrollback, without having to set the properties of the
+ tcsh.exe window.
+
+
+ This is particularly useful on Win9x, where getting a console
+ scrollback buffer seems to be practically impossible in a reasonable
+ fashion otherwise.
+
+
+ * No execution of .bat or .cmd files by name alone.
+
+ That is, you have to type foo.bat or foo.cmd to execute a batch file,
+ even if it is in your path.
+
+ This is by design. No file types other than 32-bit executables are
+ recognized by the shell. Unless you type the full name, the shell
+ attempt to execute either the name as typed ("foo" for example) or the
+ name with .exe appended to it ("foo.exe").
+
+ * The "watch" variable and the "log" builtin.
+
+ To attempt to duplicate the functionality of the log/watch combination
+ on Unix, the Windows version of shell uses NETBIOS and the semantics
+ are slightly different.
+
+ Whereas in Unix you might type
+
+ set watch=(amol tty0 root any)
+
+ in Windows you would type
+
+ set watch=(AMOL AMOLSCOMPUTER THEBOSS any)
+
+ Thus, instead of tty, the computer name of the user may be specified.
+ In this case, you will be notified if the user AMOL is logged on
+ AMOLSCOMPUTER or THEBOSS is logged on any computer.
+
+ Note that the names must be uppercase.
+
+ * The "nice" builtin.
+
+ Functionally, pretty much the same as Unix, with the range being from
+ -6 to +7, and +4 by default.
+
+ These niceness numbers map to absolutes priorities based on the
+ assumption that the process started at the typical Foreground Normal
+ Priority Class.
+
+ That means, if your shell is somehow started at a higher than normal
+ priority, even a nice +1 will lower the priority to below normal, much
+ more than just a relative lowering by one level.
+
+ * The "kill" builtin.
+
+ You can try to kill a process 4 ways:
+
+ kill -1 <pid> (which will send a sigint)
+ kill -2 <pid> (which will send a sigbreak)
+
+ 1 and 2 are only good for processes started in the same console. The
+ signals cannot be sent to other process groups (other consoles/GUI apps).
+
+ kill -3 <pid> (sends a WM_QUIT message to each window of the child>
+ Useful for closing GUI apps.
+
+ kill -7 <pid> , which will call TerminateProcess() on the process.
+ This is dangerous and should be a last resort.
+
+
+
+ Special Variables
+ -----------------
+
+ o Environment Variables:
+ *-*-*-*-*-*-*-*-*-*-*-*-*
+
+ This version of tcsh uses the following environment variables
+
+
+ - TCSHSUBSTHB (Short for "tcsh substitute hashbang"):
+
+ Supplies mappings for the shell's hashbang emulation. For example,
+
+ setenv TCSHSUBSTHB "/usr/local/bin/perl c:/bin/perl.exe;"
+
+ If the variable is thus set, any script that has
+ "#!/usr/local/bin/perl" on the first line will be run as
+ if "#!c:/bin/perl.exe" was the first line.
+
+ The terminating ";" is a must.There is a limit of 20 such pairs.
+
+ - TCSHONLYSTARTEXES
+
+ Controls whether Explorer Associations will be tried for
+ non-executables.
+
+
+ For example, "setenv TCSHONLYSTARTEXES 1" , tells tcsh to not try to
+ execute a non-exe or non-script.
+
+ The value must be EXACTLY one character long.
+
+ (a zero-length setting will not work. A length greater than 1 will
+ be assumed to be a list of extensions as below.)
+
+
+ You can also supply a semi-colon-separated list of extensions for
+ which to NOT try associations. For example, if the variable is set to
+
+ "cmd;bat",
+
+ .cmd/.bat files will be executed in the same window because the
+ default association is not used, instead an internal hack feeds them
+ to the DOS command processor.
+
+ If the file extension does not match the list, the shell will try to
+ launch an association.
+
+
+ Any changes to this variable will NOT affect the the "start" builtin.
+ That builtin ALWAYS launches associations, since the whole point of
+ using "start" is to launch an application.
+
+
+ - TCSH_NOASYNCGUI:
+
+ By default, a Windows GUI application is launched asynchronously.
+ That is, the shell does not wait for the application to terminate
+ but immediately returns you to the prompt. If this variable is set,
+ the shell will wait for the GUI application to exit before going on.
+
+ - TCSHLANG: NLS support
+
+ You can get messages in a specific language by doing:
+
+ setenv TCSHLANG <dll>, where <dll> is the name of the NLS dll.
+
+ tcsh comes with:
+
+ tcshde.dll -> German
+ tcshfr.dll -> French
+ tcshsp.dll -> Spanish
+ tcsh-it.dll -> Italian
+
+ tcshc.dll => Default "C" locale
+
+ You can change the dll at runtime by setting/unsetting this
+ variable.
+ You can specify the DLL name, or the complete path, if it is not
+ in your standard search path.
+
+ (Using tcshc.dll is useless and adds unnecessary overhead. If you
+ are using English versions, do not install the dlls)
+
+ o Shell Variables:
+ *-*-*-*-*-*-*-*
+
+ This version of tcsh recognizes the following shell variables:
+
+ - oldtitle : Stores the previous value of the title, when the "title"
+ builtin is used to change it. So, "title $oldtitle", will
+ restore the previous title.
+
+
+ - NTlamepathfix:
+
+ Normally, tcsh sets the PATH variable to be delimited by
+ "/". However, some applications may have trouble with this, so you can
+ force the shell to convert "/" to "\" before executing an external (not
+ builtin) command.
+
+ - NTslowexec:
+
+ The shell will usually try to avoid forking if a command can be executed
+ directly (using the CreateProcess() API instead of fork()). This only
+ applies to "simple" commands. These are commands that do not have their
+ output piped, redirected or are not niced or nohupped.
+
+ If you see any strange behaviour from the shell in terms of wildcard
+ expansion or quote substitution, try setting this variable (AFTER
+ setting CYGWIN noglob!!!).
+
+ - NTnoquoteprotect:
+
+
+ Ordinarily , if you pass a double quote to a command string, tcsh
+ will protect the quotes by adding backslashes. For example,
+
+ find . -name '"*.c"'
+ would get executed as
+
+ find . -name \"*.c\"
+
+ Some applications (MKS find, for example) do not like the '\'. To
+ prevent tcsh from quoting such arguments, set this variable.
+
+ Of course, it may cause other applications to break, so use at
+ your own risk.
+
+ - NTcaseifypwd:
+
+ If set, corrects case of current directory when cd'ing into it.
+ Some "filesystems" can't handle the default behaviour. Only works on
+ Windows NT.
+
+
+
+ Key bindings, clipboard support and edit functions
+ --------------------------------------------------
+
+ To use keys like function keys, arrows, insert, etc., the following
+ form of bindkey must be used:
+
+ bindkey -b N-xxx <command>
+
+ where xxx is either:
+ a) A number from 1 through 24, representing the fucntion keys.
+ For example, bindkey -b N-1 run-help
+
+ b) The strings "pgup","pgdown","end","home", "left","up","right","down",
+ "ins","del"
+ For example, bindkey -b N-del delete-char
+
+ Here are the bindings I use in my .tcshrc:
+
+ # NT specific bindkey extensions
+ bindkey -b N-up up-history
+ bindkey -b N-down down-history
+ bindkey -b N-right forward-char
+ bindkey -b N-left backward-char
+ bindkey -b N-del delete-char
+ bindkey -b N-ins overwrite-mode
+ bindkey -b N-1 which-command
+ bindkey -b N-2 expand-history
+ bindkey -b N-3 complete-word-raw
+ bindkey -b N-home beginning-of-line
+ bindkey -b N-end end-of-line
+
+ bindkey -b N-pgup e_page_up
+ bindkey -b N-pgdown e_page_down
+
+ (Note that on Win9x, you must set your console window to NOT be Auto
+ sized, and you must use the "settc" builtin to increase and then reduce
+ back the number of lines, in order to get a scrollbar. pgup and
+ pgdown will not work without a scroll bar)
+
+
+ To bind ctrl or alt combinations, use the following as examples.
+ (Alt on PC keyboards is treated as the Meta on Unix keyboards )
+
+ bindkey -b N-C-left backward-word
+ bindkey -b N-M-right forward-word
+
+ For Shift combinations:
+ bindkey -b N-S-1 backward-word
+
+ Clipboard support
+ o-o-o-o-o-o-o-o-o
+
+ You can also cut and paste to and from the clipboard directly from
+ the shell. To do this, use bindings like the following:
+
+ bindkey -b M-x e_copy_to_clipboard
+ bindkey -b M-y e_paste_from_clipboard
+
+ Then, to paste text from the clipboard into the current input
+ line, you can type:
+ M-y
+ And to copy the current shell's kill buffer to the clipboard,
+ M-x
+
+ (The kill buffer contains the last deletion from an editing
+ command. Sort of like an 'undo' buffer).
+
+ You can also use the clipboard to redirect I/O, with /dev/clipboard as
+ the destination/source file.
+
+
+
+ Editor Functions
+ o-o-o-o-o-o-o-o-o
+
+ e_dosify_next
+ -------------
+ A key bound to this editor function can be used to convert
+ unix-style paths to DOS-style paths.
+
+ For example,
+
+ bindkey -b M-/ e_dosify_next
+
+ Then, if I had line like so:
+
+ xcopy /e /u c:/nt40/system32
+
+ I would move the cursor to the C: and hit alt-/. magically, the
+ command line changes to
+
+ xcopy /e /u c:\\nt40\\system32
+
+ This function converts every '/' to '\\' until the first space.
+ If the space is escaped by a '\', the function looks for the
+ next space.
+
+ e_dosify_prev
+ -------------
+ Works like above, but on the previous word.
+
+ e_page_up
+ ---------
+ Editor function to move console window up one page. Can be bound to
+ PageUp key, for example.
+
+ e_page_down
+ ----------
+ Ditto for page down.
+
+ e_copy_to_clipboard
+ -------------------
+ See Clipboard Support above.
+
+ e_paste_from_clipboard
+ -----------------------
+ See Clipboard Support above.
diff --git a/win32/bogus.c b/win32/bogus.c
new file mode 100644
index 000000000000..5e34c4d8ee8c
--- /dev/null
+++ b/win32/bogus.c
@@ -0,0 +1,168 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/bogus.c,v 1.9 2008/10/11 12:47:39 christos Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * bogus.c: various routines that are really silly
+ * -amol
+ *
+ */
+#include "ntport.h"
+#include "sh.h"
+
+static struct passwd pass_bogus;
+static char username[20];
+static char homedir[MAX_PATH + 1];/*FIXBUF*/
+static char *this_shell="tcsh";
+
+static char dummy[2]={0,0};
+
+gid_t getuid(void) {
+ return 0;
+}
+gid_t getgid(void) {
+ return 0;
+}
+gid_t geteuid(void) {
+ return 0;
+}
+gid_t getegid(void) {
+ return 0;
+}
+#undef free
+struct passwd * getpwnam(const char *name) {
+
+ char *ptr;
+ DWORD size =20;
+ size_t esize = 0;
+
+ if (pass_bogus.pw_name == NULL) {
+ GetUserName(username,&size);
+ if (_dupenv_s(&ptr,&esize,"HOME") == 0){
+ StringCbCopy(homedir,sizeof(homedir),ptr);
+ pass_bogus.pw_dir = &homedir[0];
+ free(ptr);
+ }
+ pass_bogus.pw_name = &username[0];
+ pass_bogus.pw_shell = this_shell;
+
+
+ pass_bogus.pw_passwd= &dummy[0];
+ pass_bogus.pw_gecos=&dummy[0];
+ pass_bogus.pw_passwd= &dummy[0];
+
+ }
+ if (_stricmp(username,name) )
+ return NULL;
+ return &pass_bogus;
+}
+struct passwd * getpwuid(uid_t myuid) {
+
+ char *ptr;
+ DWORD size =20;
+ size_t esize = 0;
+
+ UNREFERENCED_PARAMETER(myuid);
+ if (pass_bogus.pw_name == NULL) {
+ GetUserName(username,&size);
+ if (_dupenv_s(&ptr,&esize,"HOME") == 0){
+ StringCbCopy(homedir,sizeof(homedir),ptr);
+ pass_bogus.pw_dir = &homedir[0];
+ free(ptr);
+ }
+ pass_bogus.pw_name = &username[0];
+ pass_bogus.pw_shell = this_shell;
+
+
+ pass_bogus.pw_passwd= &dummy[0];
+ pass_bogus.pw_gecos=&dummy[0];
+ pass_bogus.pw_passwd= &dummy[0];
+
+ }
+ return &pass_bogus;
+}
+struct group * getgrnam(char *name) {
+ UNREFERENCED_PARAMETER(name);
+ return NULL;
+}
+struct group * getgrgid(gid_t mygid) {
+ UNREFERENCED_PARAMETER(mygid);
+ return NULL;
+}
+char * ttyname(int fd) {
+
+ if (isatty(fd)) return "/dev/tty";
+ return NULL;
+}
+int times(struct tms * ignore) {
+ FILETIME c,e,kernel,user;
+
+ ignore->tms_utime=0;
+ ignore->tms_stime=0;
+ ignore->tms_cutime=0;
+ ignore->tms_cstime=0;
+ if (!GetProcessTimes(GetCurrentProcess(),
+ &c,
+ &e,
+ &kernel,
+ &user) )
+ return -1;
+
+ if (kernel.dwHighDateTime){
+ return GetTickCount();
+ }
+ //
+ // Units of 10ms. I *think* this is right. -amol 6/2/97
+ ignore->tms_stime = kernel.dwLowDateTime / 1000 /100;
+ ignore->tms_utime = user.dwLowDateTime / 1000 /100;
+
+ return GetTickCount();
+}
+int tty_getty(int fd, void*ignore) {
+ UNREFERENCED_PARAMETER(fd);
+ UNREFERENCED_PARAMETER(ignore);
+ return 0;
+}
+int tty_setty(int fd, void*ignore) {
+ UNREFERENCED_PARAMETER(fd);
+ UNREFERENCED_PARAMETER(ignore);
+ return 0;
+}
+int tty_geteightbit(void *ignore) {
+ UNREFERENCED_PARAMETER(ignore);
+ return 1;
+}
+ void
+dosetty(Char **v, struct command *t)
+{
+ UNREFERENCED_PARAMETER(v);
+ UNREFERENCED_PARAMETER(t);
+ xprintf("setty not supported in NT\n");
+}
+
diff --git a/win32/clip.c b/win32/clip.c
new file mode 100644
index 000000000000..bc057d8b4e92
--- /dev/null
+++ b/win32/clip.c
@@ -0,0 +1,570 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/clip.c,v 1.9 2006/03/05 08:59:36 amold Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * clip.c : support for clipboard functions.
+ * -amol
+ *
+ */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdio.h>
+#include "sh.h"
+#include "ed.h"
+
+BOOL InitApplication(HINSTANCE);
+BOOL InitInstance(HINSTANCE, int);
+LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
+
+
+HWND ghwndmain;
+
+extern int ctrl_handler(DWORD);
+extern void c_insert(int);
+
+/*
+ * Creating a hidden window may not be strictly necessary on
+ * NT, but why tempt fate ?
+ * -amol
+ */
+
+void clipper_thread(void) {
+
+ MSG msg;
+ HINSTANCE hInstance = GetModuleHandle(NULL);
+
+
+ if (!InitApplication(hInstance)) {
+ return ;
+ }
+
+ if (!InitInstance(hInstance, 0)) {
+ return ;
+ }
+ // Main message loop:
+ while (GetMessage(&msg, NULL, 0, 0)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ if ( !ctrl_handler(CTRL_CLOSE_EVENT))
+ init_clipboard();
+ return;
+}
+void init_clipboard(void) {
+ HANDLE ht;
+ DWORD tid;
+
+ ht = CreateThread(NULL,gdwStackSize,
+ (LPTHREAD_START_ROUTINE)clipper_thread, NULL,0,&tid);
+
+ if (!ht)
+ abort();
+ CloseHandle(ht);
+}
+
+BOOL InitApplication(HINSTANCE hInstance)
+{
+ WNDCLASS wc;
+
+
+ // Fill in window class structure with parameters that describe
+ // the main window.
+ wc.style = CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = (WNDPROC)WndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = hInstance;
+ wc.hIcon = NULL;//LoadIcon (hInstance, szAppName);
+ wc.hCursor = NULL;//LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)IntToPtr(COLOR_WINDOW+1);
+
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = "tcshclipboard";
+
+ return RegisterClass(&wc);
+}
+
+//
+// FUNCTION: InitInstance(HANDLE, int)
+//
+// PURPOSE: Saves instance handle and creates main window
+//
+// COMMENTS:
+//
+// In this function, we save the instance handle in a global variable and
+// create and display the main program window.
+//
+BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) {
+ HWND hWnd;
+
+
+ UNREFERENCED_PARAMETER(nCmdShow);
+
+ hWnd = CreateWindow("tcshclipboard", "tcshclipboard",
+ WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
+ NULL, NULL, hInstance, NULL);
+
+ if (!hWnd) {
+ return (FALSE);
+ }
+
+ UpdateWindow(hWnd);
+ ghwndmain = hWnd;
+
+ return (TRUE);
+}
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+
+ switch (message) {
+
+ case WM_DESTROYCLIPBOARD:
+ break;
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+
+ default:
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+ }
+ return (0);
+}
+
+CCRETVAL e_copy_to_clipboard(Char c) {
+ unsigned char *cbp;
+ Char *kp;
+ int err;
+ size_t len;
+ unsigned char *clipbuf;
+ HANDLE hclipbuf;
+
+ UNREFERENCED_PARAMETER(c);
+
+ if (!ghwndmain)
+ return (CC_ERROR);
+
+ if (KillRingLen == 0)
+ return (CC_ERROR);
+
+ len = Strlen(KillRing[YankPos].buf);
+
+ hclipbuf = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, len+2);
+ if (!hclipbuf)
+ return (CC_ERROR);
+ clipbuf = (unsigned char*)GlobalLock(hclipbuf);
+
+ if (!clipbuf){
+ err = GetLastError();
+ GlobalFree(hclipbuf);
+ return (CC_ERROR);
+ }
+
+ kp = KillRing[YankPos].buf;
+ cbp = clipbuf;
+
+ while(*kp != '\0') {
+ *cbp = (u_char)(*kp & CHAR);
+ cbp++;kp++;
+ }
+ *cbp = 0;
+
+ GlobalUnlock(clipbuf);
+
+ if (!OpenClipboard(ghwndmain))
+ goto error;
+
+ if (!EmptyClipboard())
+ goto error;
+
+ if (SetClipboardData(CF_TEXT,hclipbuf) != hclipbuf){
+ err = GetLastError();
+ goto error;
+
+ }
+
+ CloseClipboard();
+ return (CC_NORM);
+error:
+ GlobalFree(hclipbuf);
+ CloseClipboard();
+ return (CC_ERROR);
+}
+CCRETVAL e_paste_from_clipboard(Char c) {
+ HANDLE hclip;
+ unsigned char *cbp;
+ Char *cp;
+ int len;
+ unsigned char *clipbuf;
+
+
+
+ UNREFERENCED_PARAMETER(c);
+
+ if (!ghwndmain)
+ return (CC_ERROR);
+ if (!IsClipboardFormatAvailable(CF_TEXT))
+ return CC_ERROR;
+
+ if (!OpenClipboard(ghwndmain))
+ return CC_ERROR;
+
+
+ hclip = GetClipboardData(CF_TEXT);
+ if (hclip) {
+ clipbuf = (unsigned char*)GlobalLock(hclip);
+
+ cbp = clipbuf;
+ len = 0;
+
+ while(*cbp && *cbp != '\r') {
+ len++;
+ cbp++;
+ }
+ cbp = clipbuf;
+
+ cp = Cursor;
+
+ c_insert(len);
+
+ if (LastChar + len >= InputLim)
+ goto error;
+
+ while(*cbp && *cbp !='\r' && (cp <LastChar) ) {
+ *cp = *cbp ;
+ cp++;cbp++;
+ }
+ Cursor = cp;
+ GlobalUnlock(hclip);
+ }
+ CloseClipboard();
+
+ return (CC_REFRESH);
+error:
+ return (CC_ERROR);
+}
+
+int is_dev_clipboard_active=0;
+HANDLE ghdevclipthread;
+
+/* Reads from pipe and write to clipboard */
+void clip_writer_proc(HANDLE hinpipe) {
+ unsigned char *realbuf;
+ unsigned char *clipbuf;
+ unsigned char *ptr;
+ DWORD bread=0,spleft,err,i,rbsize;
+ DWORD ptrloc;
+ HANDLE hclipbuf;
+
+
+ rbsize = 4096;
+ realbuf = heap_alloc(rbsize);
+ ptr = realbuf;
+ ptrloc = 0;
+ spleft = rbsize;
+
+ while(spleft) {
+ if (!ReadFile(hinpipe,ptr,spleft,&bread,NULL)) {
+ spleft = GetLastError();
+ dprintf("hinpipe returend %d\n",spleft);
+ if (spleft == ERROR_BROKEN_PIPE)
+ break;
+ }
+ if (bread == 0)
+ break;
+ ptr += bread;
+ ptrloc += bread;
+ spleft -=bread;
+
+ if (spleft <=0){
+ u_char *tmp;
+
+ rbsize <<=1;
+
+ tmp = realbuf;
+ realbuf = heap_realloc(realbuf,rbsize);
+ if (!realbuf) {
+ realbuf = tmp;
+ break;
+ }
+ spleft += rbsize >> 1;
+
+ ptr = realbuf+ptrloc;
+
+ dprintf("updated size now %d, splef %d, ptrloc %d, ptr 0x%08x, realbuf 0x%08x\n",rbsize,spleft,ptrloc,ptr,realbuf);
+ }
+ }
+ CloseHandle(hinpipe);
+
+ bread = rbsize-spleft;
+
+ hclipbuf = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, bread+256);
+ if (!hclipbuf) {
+ is_dev_clipboard_active=0;
+ return;
+ }
+ clipbuf = (u_char*)GlobalLock(hclipbuf);
+
+ if (!clipbuf){
+ err = GetLastError();
+ GlobalFree(hclipbuf);
+ is_dev_clipboard_active=0;
+ return ;
+ }
+ ptr = clipbuf;
+ for (i=0;i <bread;i++) {
+
+ if (realbuf[i] == '\n' && (i >0 && realbuf[i-1] != '\r') )
+ *ptr++ = '\r';
+
+ *ptr++ =realbuf[i];
+
+ if ((ptr - clipbuf) >= rbsize)
+ break;
+ }
+ *ptr=0;
+
+ heap_free(realbuf);
+
+ GlobalUnlock(clipbuf);
+
+ if (!OpenClipboard(ghwndmain))
+ goto error;
+
+ if (!EmptyClipboard())
+ goto error;
+
+ if (SetClipboardData(CF_TEXT,hclipbuf) != hclipbuf){
+ err = GetLastError();
+ goto error;
+
+ }
+ CloseClipboard();
+ is_dev_clipboard_active=0;
+ return ;
+error:
+ is_dev_clipboard_active=0;
+ GlobalFree(hclipbuf);
+ CloseClipboard();
+}
+HANDLE create_clip_writer_thread(void) {
+ HANDLE hread,hwrite;
+ DWORD tid;
+ SECURITY_ATTRIBUTES secd;
+
+ if (is_dev_clipboard_active)
+ return INVALID_HANDLE_VALUE;
+ secd.nLength=sizeof(secd);
+ secd.lpSecurityDescriptor=NULL;
+ secd.bInheritHandle=FALSE;
+
+ if (!CreatePipe(&hread,&hwrite,&secd,0)) {
+ abort();
+ }
+ is_dev_clipboard_active = 1;
+ ghdevclipthread = CreateThread(NULL,gdwStackSize,
+ (LPTHREAD_START_ROUTINE)clip_writer_proc, hread,0,&tid);
+// CloseHandle(ht);
+ return hwrite;
+}
+
+/* Read from clipboard and write to pipe */
+void clip_reader_proc(HANDLE houtpipe) {
+
+ HANDLE hclip;
+ unsigned char *cbp;
+ unsigned char *clipbuf;
+ unsigned char * outbuf,*ptr;
+ DWORD bwrote, len;
+ DWORD obsize;
+
+ obsize = 4096;
+ outbuf = heap_alloc(obsize);
+ ptr = outbuf;
+
+
+ if (!IsClipboardFormatAvailable(CF_TEXT))
+ goto done ;
+
+ if (!OpenClipboard(ghwndmain))
+ goto done ;
+
+
+ len = 0;
+ hclip = GetClipboardData(CF_TEXT);
+ if (hclip) {
+ clipbuf = (unsigned char*)GlobalLock(hclip);
+
+ cbp = clipbuf;
+
+ while(*cbp ) {
+ *ptr++ = *cbp++;
+ len++;
+ if (len == obsize) {
+ obsize <<= 1;
+ outbuf = heap_realloc(outbuf,obsize);
+ if (!outbuf)
+ break;
+ ptr = outbuf+len;
+ }
+ }
+ GlobalUnlock(hclip);
+ }
+ CloseClipboard();
+
+ if (!WriteFile(houtpipe,outbuf,len,&bwrote,NULL)) {
+ ;
+ }
+ CloseHandle(houtpipe);
+ heap_free(outbuf);
+
+done:
+ is_dev_clipboard_active=0;
+ return;
+}
+HANDLE create_clip_reader_thread(void) {
+ HANDLE hread,hwrite;
+ DWORD tid;
+ SECURITY_ATTRIBUTES secd;
+
+ if (is_dev_clipboard_active)
+ return INVALID_HANDLE_VALUE;
+
+ secd.nLength=sizeof(secd);
+ secd.lpSecurityDescriptor=NULL;
+ secd.bInheritHandle=FALSE;
+
+ if (!CreatePipe(&hread,&hwrite,&secd,0)) {
+ abort();
+ }
+ is_dev_clipboard_active = 1;
+ ghdevclipthread = CreateThread(NULL,gdwStackSize,
+ (LPTHREAD_START_ROUTINE)clip_reader_proc, hwrite,0,&tid);
+ return hread;
+}
+
+CCRETVAL
+e_dosify_next(Char c)
+{
+ register Char *cp, *buf, *bp;
+ int len;
+ BOOL bDone = FALSE;
+
+
+ USE(c);
+ if (Cursor == LastChar)
+ return(CC_ERROR);
+
+ // worst case assumption
+ buf = heap_alloc(( LastChar - Cursor + 1)*2*sizeof(Char));
+
+ cp = Cursor;
+ bp = buf;
+ len = 0;
+
+ while( cp < LastChar) {
+ if ( ((*cp & CHAR) == ' ') && ((cp[-1] & CHAR) != '\\') )
+ bDone = TRUE;
+ if (!bDone && (*cp & CHAR) == '/') {
+ *bp++ = '\\' | (Char)(*cp & ~(*cp & CHAR) );
+ *bp++ = '\\' | (Char)(*cp & ~(*cp & CHAR) );
+
+ len++;
+
+ cp++;
+ }
+ else
+ *bp++ = *cp++;
+
+ len++;
+ }
+ if (Cursor+ len >= InputLim) {
+ heap_free(buf);
+ return CC_ERROR;
+ }
+ cp = Cursor;
+ bp = buf;
+ while(len > 0) {
+ *cp++ = *bp++;
+ len--;
+ }
+
+ heap_free(buf);
+
+ Cursor = cp;
+
+ if(LastChar < Cursor + len)
+ LastChar = Cursor + len;
+
+ return (CC_REFRESH);
+}
+/*ARGSUSED*/
+CCRETVAL
+e_dosify_prev(Char c)
+{
+ register Char *cp;
+
+ USE(c);
+ if (Cursor == InputBuf)
+ return(CC_ERROR);
+ /* else */
+
+ cp = Cursor-1;
+ /* Skip trailing spaces */
+ while ((cp > InputBuf) && ( (*cp & CHAR) == ' '))
+ cp--;
+
+ while (cp > InputBuf) {
+ if ( ((*cp & CHAR) == ' ') && ((cp[-1] & CHAR) != '\\') )
+ break;
+ cp--;
+ }
+ if(cp != InputBuf)
+ Cursor = cp + 1;
+ else
+ Cursor = cp;
+
+ return e_dosify_next(0);
+}
+extern BOOL ConsolePageUpOrDown(BOOL);
+CCRETVAL
+e_page_up(Char c) //blukas@broadcom.com
+{
+ USE(c);
+ ConsolePageUpOrDown(TRUE);
+ return (CC_REFRESH);
+}
+CCRETVAL
+e_page_down(Char c)
+{
+ USE(c);
+ ConsolePageUpOrDown(FALSE);
+ return (CC_REFRESH);
+}
diff --git a/win32/console.c b/win32/console.c
new file mode 100644
index 000000000000..220d56eaea94
--- /dev/null
+++ b/win32/console.c
@@ -0,0 +1,636 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/console.c,v 1.9 2006/08/27 01:13:28 amold Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * console.c: hacks to do various cursor movement/attribute things
+ * -amol
+ */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <wincon.h>
+#include <stdio.h>
+#include "ntport.h"
+
+
+// int to SHORT. caused by all the stupid functions that take WORDs
+#pragma warning(disable:4244)
+
+void ScrollBuf(HANDLE,CONSOLE_SCREEN_BUFFER_INFO*,int);
+void NT_MoveToLineOrChar(int ,int ) ;
+WORD get_attributes();
+
+
+#define FSHIN 16 /* Preferred desc for shell input */
+#define FSHOUT 17 /* Preferred desc for shell input */
+
+#define FOREGROUND_BLACK (FOREGROUND_RED |FOREGROUND_GREEN | FOREGROUND_BLUE)
+#define FOREGROUND_WHITE 0
+#define BACKGROUND_BLACK (BACKGROUND_RED |BACKGROUND_GREEN | BACKGROUND_BLUE)
+#define BACKGROUND_WHITE 0
+
+static WORD wNormalAttributes;
+
+
+static int nt_is_raw;
+//
+// The following are used to optimize some console routines. It avoids having
+// to call GetConsoleScreenBufferInfo.
+// Seems to have helped the speed a bit. -amol
+//
+HANDLE ghstdout;
+HANDLE ghReverse;
+
+//
+// This function is called to set the values for above variables.
+//
+void redo_console(void) {
+
+ CONSOLE_SCREEN_BUFFER_INFO scrbuf;
+ HANDLE hTemp= GetStdHandle(STD_OUTPUT_HANDLE);
+ WORD dbga;
+ DWORD wrote;
+ COORD origin = {0,0};
+
+ if (!DuplicateHandle(GetCurrentProcess(),hTemp,GetCurrentProcess(),
+ &ghstdout,0,TRUE,DUPLICATE_SAME_ACCESS) ) {
+ ;
+ }
+
+ if(!GetConsoleScreenBufferInfo(ghstdout, &scrbuf) ) {
+ wNormalAttributes = FOREGROUND_BLACK | BACKGROUND_WHITE;
+ }
+ else
+ wNormalAttributes = scrbuf.wAttributes;
+
+ ghReverse = CreateConsoleScreenBuffer(GENERIC_READ|GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ CONSOLE_TEXTMODE_BUFFER,
+ NULL);
+
+ dbga = ((wNormalAttributes & 0x00f0) >> 4) |
+ ((wNormalAttributes & 0x000f) << 4) ;
+
+ FillConsoleOutputAttribute(ghReverse,dbga,
+ scrbuf.dwSize.X*scrbuf.dwSize.Y,
+ origin,
+ &wrote);
+}
+void nt_term_cleanup(void) {
+ CloseHandle(ghstdout);
+}
+void nt_term_init() {
+
+ DWORD dwmode;
+ HANDLE hinput =GetStdHandle(STD_INPUT_HANDLE);
+
+ if (!GetConsoleMode(hinput,&dwmode) ){
+ ;
+ }
+ if(!SetConsoleMode(hinput,dwmode | ENABLE_WINDOW_INPUT) ){
+ return;
+ }
+
+ redo_console();
+
+ return;
+}
+int do_nt_check_cooked_mode(void) {
+
+ return !nt_is_raw;
+}
+void do_nt_raw_mode() {
+
+ DWORD dwmode;
+ HANDLE hinput =(HANDLE)_get_osfhandle(FSHIN);
+
+ if (hinput == INVALID_HANDLE_VALUE)
+ return;
+ if (!GetConsoleMode(hinput,&dwmode) ){
+ ;
+ }
+ if(!SetConsoleMode(hinput,dwmode & (~(
+ ENABLE_LINE_INPUT |ENABLE_ECHO_INPUT
+ | ENABLE_PROCESSED_INPUT)| ENABLE_WINDOW_INPUT )
+ ) ){
+ return;
+ }
+ nt_is_raw = 1;
+ return;
+}
+void do_nt_cooked_mode() {
+
+ DWORD dwmode;
+ HANDLE hinput =(HANDLE)_get_osfhandle(FSHIN);
+
+ if (hinput == INVALID_HANDLE_VALUE)
+ return;
+ if (!GetConsoleMode(hinput,&dwmode) ){
+ ;
+ }
+ if(!SetConsoleMode(hinput,dwmode | ( (
+ ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT |
+ ENABLE_PROCESSED_INPUT) )
+ ) ){
+ }
+ nt_is_raw = 0;
+ return;
+}
+//
+// this function is a bit ugly, but I don't know how to do it better
+// -amol
+//
+int nt_ClearEOL( void) {
+
+ CONSOLE_SCREEN_BUFFER_INFO scrbuf;
+ HANDLE hStdout =ghstdout ;
+ DWORD numwrote;
+ char errbuf[128];/*FIXME: uninitialized*/
+ int num=0;
+ COORD savepos;
+
+
+ if (hStdout == INVALID_HANDLE_VALUE){
+ ExitProcess(0xFFFF);
+ }
+ if(!GetConsoleScreenBufferInfo(hStdout, &scrbuf) ) {
+ return 0 ;
+ }
+ num =2048;
+
+ savepos = scrbuf.dwCursorPosition;
+ if (!FillConsoleOutputCharacter(hStdout,' ',num,scrbuf.dwCursorPosition,
+ &numwrote) ){
+ dprintf("error from FillCons %s",errbuf);
+ }
+ else if (!FillConsoleOutputAttribute(hStdout,scrbuf.wAttributes, num,
+ scrbuf.dwCursorPosition,&numwrote)) {
+ dprintf("error from FillConsAttr %s",errbuf);
+ }
+ return 0;
+}
+void nt_move_next_tab(void) {
+
+ CONSOLE_SCREEN_BUFFER_INFO scrbuf;
+ HANDLE hStdout = ghstdout;
+ int where;
+
+ if(!GetConsoleScreenBufferInfo(hStdout, &scrbuf) ) {
+ ;
+ }
+ where = 8 - (scrbuf.dwCursorPosition.X+1)%8;
+ scrbuf.dwCursorPosition.X += where;
+ if (!SetConsoleCursorPosition(hStdout, scrbuf.dwCursorPosition) ) {
+ ;
+ }
+
+}
+void NT_VisibleBell(void) {
+
+ if(ghReverse != INVALID_HANDLE_VALUE) {
+ SetConsoleActiveScreenBuffer(ghReverse);
+ Sleep(100);
+ SetConsoleActiveScreenBuffer(ghstdout);
+
+ }
+
+}
+void NT_WrapHorizontal(void) {
+ SMALL_RECT wnd;
+ CONSOLE_SCREEN_BUFFER_INFO scrbuf;
+
+
+ if (ghstdout == INVALID_HANDLE_VALUE){
+ return;
+ }
+ if(!GetConsoleScreenBufferInfo(ghstdout, &scrbuf) ) {
+ return;
+ }
+ //absolute movement
+ wnd.Left = 0;//scrbuf.srWindow.Left ;
+ wnd.Right = scrbuf.srWindow.Right- scrbuf.srWindow.Left + 1;
+ wnd.Top = scrbuf.srWindow.Top;
+ wnd.Bottom = scrbuf.srWindow.Bottom;
+
+ SetConsoleWindowInfo(ghstdout,TRUE,&wnd);
+}
+void ScrollBufHorizontal(HANDLE hOut, CONSOLE_SCREEN_BUFFER_INFO *scrbuf,
+ int where) {
+ SMALL_RECT wnd;
+ int diff;
+ CHAR_INFO chr;
+
+
+ //absolute movement
+ wnd.Left = (where - scrbuf->srWindow.Right) + scrbuf->srWindow.Left ;
+ wnd.Right = where;
+ wnd.Top = scrbuf->srWindow.Top;
+ wnd.Bottom = scrbuf->srWindow.Bottom;
+
+ //diff = scrbuf->srWindow.Right - where;
+ //dprintf("\tdiff1 %d\n",diff);
+
+ diff = scrbuf->dwSize.X - where -1;
+
+ if (diff < 0) { //would scroll past console buffer
+
+ chr.Char.AsciiChar = ' ';
+ chr.Attributes = scrbuf->wAttributes;
+
+ scrbuf->dwCursorPosition.Y = scrbuf->srWindow.Top ;
+ scrbuf->dwCursorPosition.X = scrbuf->srWindow.Right+ diff;
+
+ dprintf("scroll diff %d\n",diff);
+ if (!ScrollConsoleScreenBuffer(hOut,&(scrbuf->srWindow),
+ NULL,
+ scrbuf->dwCursorPosition,&chr))
+ ;
+
+ return;
+ }
+
+ SetConsoleWindowInfo(hOut,TRUE,&wnd);
+}
+// relative movement of "where". line is 1 if we want to move to a line,
+// or 0 if the movement is horizontal
+void NT_MoveToLineOrChar(int where,int line) {
+
+ CONSOLE_SCREEN_BUFFER_INFO scrbuf;
+ HANDLE hStdout = ghstdout;
+
+
+ if (hStdout == INVALID_HANDLE_VALUE){
+ return;
+ }
+ if(!GetConsoleScreenBufferInfo(hStdout, &scrbuf) ) {
+ return;
+ }
+
+ if (line){
+ if ( ((scrbuf.dwCursorPosition.Y+where)> (scrbuf.srWindow.Bottom-1))
+ &&( where >0)){
+ ScrollBuf(hStdout,&scrbuf,where);
+ scrbuf.dwCursorPosition.Y += where;
+ }
+ else
+ scrbuf.dwCursorPosition.Y += where;
+ }
+ else{
+ if ( (where> (scrbuf.srWindow.Right)) &&( where >0)){
+ ScrollBufHorizontal(hStdout,&scrbuf,where);
+ }
+ scrbuf.dwCursorPosition.X = where;
+ }
+ if (scrbuf.dwCursorPosition.X < 0 || scrbuf.dwCursorPosition.Y <0)
+ return;
+ if (!SetConsoleCursorPosition(hStdout, scrbuf.dwCursorPosition) ) {
+ return;
+ }
+
+}
+void ScrollBuf(HANDLE hOut, CONSOLE_SCREEN_BUFFER_INFO *scrbuf,int where) {
+ SMALL_RECT wnd;
+ int diff;
+ CHAR_INFO chr;
+ COORD newpos;
+
+
+ wnd.Left = 0;
+ wnd.Right = 0;
+ wnd.Top = where;
+ wnd.Bottom = where;
+
+ //dwSize is not 0-based, so add 1 to proposed location
+ diff = scrbuf->srWindow.Bottom + where + 1;
+
+ diff = scrbuf->dwSize.Y - diff;
+
+ if (diff < 0) { //would scroll past console buffer
+
+ chr.Char.AsciiChar = ' ';
+ chr.Attributes = scrbuf->wAttributes;
+
+ newpos.Y = scrbuf->srWindow.Top + diff;
+ newpos.X = scrbuf->srWindow.Left;
+
+ dprintf("scroll diff %d\n",diff);
+ if (!ScrollConsoleScreenBuffer(hOut,&(scrbuf->srWindow),
+ NULL,
+ newpos,&chr))
+ ;
+
+ // need this to be in sync with tcsh
+ scrbuf->dwCursorPosition.Y += diff;
+ return;
+ }
+
+ SetConsoleWindowInfo(hOut,FALSE,&wnd);
+}
+BOOL ConsolePageUpOrDown(BOOL Up) {
+
+ HANDLE hStdout = ghstdout;
+ CONSOLE_SCREEN_BUFFER_INFO scrbuf;
+ SMALL_RECT srect;
+ short diff;
+
+ if(!GetConsoleScreenBufferInfo(hStdout, &scrbuf) ) {
+ return FALSE;
+ }
+ diff = scrbuf.srWindow.Bottom -scrbuf.srWindow.Top+1 ;
+
+
+ if (Up)
+ diff = -diff;
+
+ if ((scrbuf.srWindow.Top + diff > 0) &&
+ (scrbuf.srWindow.Bottom + diff < scrbuf.dwSize.Y)) {
+ srect.Top = diff;
+ srect.Bottom = diff;
+ srect.Left = 0;
+ srect.Right = 0;
+
+ if (! SetConsoleWindowInfo( hStdout, FALSE, &srect)) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+int nt_getsize(int * lins, int * cols, int *visiblecols) {
+ CONSOLE_SCREEN_BUFFER_INFO scrbuf;
+ HANDLE hStdout = ghstdout;
+
+ if(!GetConsoleScreenBufferInfo(hStdout, &scrbuf) ) {
+ ;
+ }
+ *lins = scrbuf.srWindow.Bottom -scrbuf.srWindow.Top+1 ;
+
+ if(visiblecols)
+ *visiblecols = scrbuf.srWindow.Right -scrbuf.srWindow.Left +1;
+
+ *cols = scrbuf.dwSize.X;
+ return 1;
+}
+void nt_set_size(int lins, int cols) {
+ SMALL_RECT srect;
+ CONSOLE_SCREEN_BUFFER_INFO scrbuf;
+ int expand;
+
+ /* The screen buffer visible window is specified as co-ordinates
+ * not size. Therefore, it must be zero-based
+ */
+ cols--;
+ lins--;
+
+ srect.Left = srect.Top = 0;
+ srect.Right = cols;
+ srect.Bottom = lins;
+
+ if(!GetConsoleScreenBufferInfo(ghstdout, &scrbuf) )
+ return;
+
+ expand = 0;
+ if (scrbuf.dwSize.X < cols){
+ expand = 1;
+ scrbuf.dwSize.X = cols+1;
+ }
+ if (scrbuf.dwSize.Y < lins){
+ expand = 1;
+ scrbuf.dwSize.Y = lins+1;
+ }
+
+ if (expand && !SetConsoleScreenBufferSize(ghstdout,scrbuf.dwSize))
+ return;
+
+ if(!SetConsoleWindowInfo(ghstdout,TRUE,&srect)){
+ int err;
+ err=GetLastError();
+ dprintf("error %d\n",err);
+ }
+}
+void NT_ClearEOD(void) {
+ CONSOLE_SCREEN_BUFFER_INFO scrbuf;
+ DWORD numwrote;
+ COORD origin;
+ int ht,wt;
+ HANDLE hStdout = ghstdout;//GetStdHandle(STD_OUTPUT_HANDLE);
+
+ if (hStdout == INVALID_HANDLE_VALUE){
+ return ;
+ }
+ if(!GetConsoleScreenBufferInfo(hStdout, &scrbuf) ) {
+ return ;
+ }
+ origin = scrbuf.dwCursorPosition;
+ ht = scrbuf.dwSize.Y - origin.Y;
+ wt = scrbuf.dwSize.X - origin.X;
+ if(!FillConsoleOutputCharacter(hStdout,' ',ht*wt,origin,&numwrote) ) {
+ return ;
+ }
+ if (!FillConsoleOutputAttribute(hStdout,scrbuf.wAttributes, ht*wt,
+ scrbuf.dwCursorPosition,&numwrote)) {
+ return;
+ }
+ return;
+}
+void NT_ClearScreen(void) {
+ CONSOLE_SCREEN_BUFFER_INFO scrbuf;
+ DWORD numwrote;
+ COORD origin={0,0};
+ HANDLE hStdout = ghstdout;//GetStdHandle(STD_OUTPUT_HANDLE);
+
+ if (hStdout == INVALID_HANDLE_VALUE){
+ ;
+ }
+ if(!GetConsoleScreenBufferInfo(hStdout, &scrbuf) ) {
+ ;
+ }
+ origin.X = scrbuf.srWindow.Left;
+ origin.Y = scrbuf.srWindow.Top;
+ if(!FillConsoleOutputCharacter(hStdout,' ',scrbuf.dwSize.X*scrbuf.dwSize.Y,
+ origin,&numwrote) ) {
+ ;
+ }
+ if (!FillConsoleOutputAttribute(hStdout,scrbuf.wAttributes,
+ scrbuf.dwSize.X*scrbuf.dwSize.Y,origin,&numwrote)) {
+ ;
+ }
+ if (!SetConsoleCursorPosition(hStdout, origin) ) { // home cursor
+ ;
+ }
+ return;
+}
+void NT_ClearScreen_WholeBuffer(void) {
+ CONSOLE_SCREEN_BUFFER_INFO scrbuf;
+ DWORD numwrote;
+ COORD origin={0,0};
+ HANDLE hStdout = ghstdout;
+
+ if (hStdout == INVALID_HANDLE_VALUE){
+ ;
+ }
+ if(!GetConsoleScreenBufferInfo(hStdout, &scrbuf) ) {
+ ;
+ }
+ if(!FillConsoleOutputCharacter(hStdout,' ',scrbuf.dwSize.X*scrbuf.dwSize.Y,
+ origin,&numwrote) ) {
+ ;
+ }
+ if (!FillConsoleOutputAttribute(hStdout,scrbuf.wAttributes,
+ scrbuf.dwSize.X*scrbuf.dwSize.Y,origin,&numwrote)) {
+ ;
+ }
+ if (!SetConsoleCursorPosition(hStdout, origin) ) { // home cursor
+ ;
+ }
+ return;
+}
+
+#ifndef COLOR_LS_F
+void set_cons_attr(char *attr2) {
+ char cp[3];
+ USHORT attr;
+ HANDLE outhandle = (HANDLE)_get_osfhandle(FSHOUT);
+ static WORD old_attribs;
+ CONSOLE_SCREEN_BUFFER_INFO scrbuf;
+
+ if (!old_attribs) {
+ if(!GetConsoleScreenBufferInfo(outhandle, &scrbuf) ) {
+ return;
+ }
+ old_attribs = scrbuf.wAttributes;
+ }
+ cp[0] = (unsigned char)(attr2[0]);
+ cp[1] = (unsigned char)(attr2[1]);
+ cp[2] = 0;
+ if (cp[0] != 'g' || cp[1] != 'g')
+ attr = (USHORT)strtol(cp,NULL,16);
+ else{
+ attr = old_attribs;
+ old_attribs=0;
+ }
+
+ SetConsoleTextAttribute(outhandle, attr );
+}
+#endif /* !COLOR_LS_F */
+
+
+/*
+ color escape sequences (ISO 6429, aixterm)
+ - nayuta
+ */
+
+
+WORD get_attributes() {
+ CONSOLE_SCREEN_BUFFER_INFO scrbuf;
+ if (!GetConsoleScreenBufferInfo(ghstdout, &scrbuf))
+ return 0x70; // ERROR: return white background, black text
+ return scrbuf.wAttributes;
+}
+
+
+#ifndef COMMON_LVB_REVERSE_VIDEO
+#define COMMON_LVB_REVERSE_VIDEO 0x4000
+#define COMMON_LVB_UNDERSCORE 0x8000
+#endif
+
+
+void set_attributes(const unsigned char *color) {
+
+ static const int colors[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+ WORD wAttributes;
+ const char *t;
+
+ if (color[0] == '\x1b' && color[1] == '[')
+ color += 2;
+
+ if (!('0' <= color[0] && color[0] <= '9')) {
+ SetConsoleTextAttribute(ghstdout, wNormalAttributes);
+ return;
+ }
+
+ wAttributes = get_attributes();
+ t = (char*)color;
+
+ while (t) {
+ int n = atoi(t);
+
+ if ((t = strchr(t, ';')) != NULL)
+ t++;
+
+ if (n == 0) // Normal (default)
+ wAttributes = wNormalAttributes;
+ else if (n == 1) // Bold
+ wAttributes |= FOREGROUND_INTENSITY;
+ else if (n == 4) // Underlined
+ wAttributes |= COMMON_LVB_UNDERSCORE;
+ else if (n == 5) // Blink (appears as BACKGROUND_INTENSITY)
+ wAttributes |= BACKGROUND_INTENSITY;
+ else if (n == 7) // Inverse
+ wAttributes |= COMMON_LVB_REVERSE_VIDEO;
+ else if (n == 21) // Not bold
+ wAttributes &= ~FOREGROUND_INTENSITY;
+ else if (n == 24) // Not underlined
+ wAttributes &= ~COMMON_LVB_UNDERSCORE;
+ else if (n == 25) // Steady (not blinking)
+ wAttributes &= ~BACKGROUND_INTENSITY;
+ else if (n == 27) // Positive (not inverse)
+ wAttributes &= ~COMMON_LVB_REVERSE_VIDEO;
+ else if (30 <= n && n <= 37) // Set foreground color
+ wAttributes = (wAttributes & ~0x0007) | colors[n - 30];
+ else if (n == 39) // Set foreground color to default
+ wAttributes = (wAttributes & ~0x0007) | (wNormalAttributes & 0x0007);
+ else if (40 <= n && n <= 47) // Set background color
+ wAttributes = (wAttributes & ~0x0070) | (colors[n - 40] << 4);
+ else if (n == 49) // Set background color to default
+ wAttributes = (wAttributes & ~0x0070) | (wNormalAttributes & 0x0070);
+ else if (90 <= n && n <= 97) // Set foreground color (bright)
+ wAttributes = (wAttributes & ~0x0007) | colors[n - 90]
+ | FOREGROUND_INTENSITY;
+ else if (100 <= n && n <= 107) // Set background color (bright)
+ wAttributes = (wAttributes & ~0x0070) | (colors[n - 100] << 4)
+ | BACKGROUND_INTENSITY;
+ else // (default)
+ wAttributes = wNormalAttributes;
+ }
+
+ // Though Windows' console supports COMMON_LVB_REVERSE_VIDEO,
+ // it seems to be buggy. So we must simulate it.
+ if (wAttributes & COMMON_LVB_REVERSE_VIDEO)
+ wAttributes = (wAttributes & COMMON_LVB_UNDERSCORE)
+ | ((wAttributes & 0x00f0) >> 4) | ((wAttributes & 0x000f) << 4);
+ SetConsoleTextAttribute(ghstdout, wAttributes);
+}
+void StartHighlight(void)
+{
+}
+void StopHighlight(void)
+{
+}
diff --git a/win32/customstep.cmd b/win32/customstep.cmd
new file mode 100644
index 000000000000..85e6b0f6f2f8
--- /dev/null
+++ b/win32/customstep.cmd
@@ -0,0 +1,7 @@
+@echo off
+setlocal
+call "%VS90COMNTOOLS%"\vsvars32.bat
+pushd "%1"
+copy config\win32 config.h
+nmake -f win32\makefile.win32 prebuild
+popd
diff --git a/win32/dirent.c b/win32/dirent.c
new file mode 100644
index 000000000000..bfe7d075c4b1
--- /dev/null
+++ b/win32/dirent.c
@@ -0,0 +1,364 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/dirent.c,v 1.9 2006/04/07 00:57:59 amold Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* dirent.c
+ * directory interface functions. Sort of like dirent functions on unix.
+ * Also allow browsing network shares as if they were directories
+ *
+ * -amol
+ *
+ */
+#define WIN32_LEAN_AND_MEAN
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+#include <direct.h>
+#include "dirent.h"
+#include <winnetwk.h>
+
+#ifndef WINDOWS_ONLY
+#define STRSAFE_NO_DEPRECATE
+#endif /* WINDOWS_ONLY*/
+#define STRSAFE_LIB
+#define STRSAFE_NO_CCH_FUNCTIONS
+#include <strsafe.h>
+
+#pragma intrinsic("memset")
+
+static HANDLE open_enum(char *,WIN32_FIND_DATA*);
+static void close_enum(DIR*) ;
+static int enum_next_share(DIR*);
+
+typedef struct _enum_h {
+ unsigned char *netres;
+ HANDLE henum;
+} nethandle_t;
+
+static int inode= 1; // useless piece that some unix programs need
+DIR * opendir(const char *inbuf) {
+
+ DIR *dptr;
+ WIN32_FIND_DATA fdata = {0};
+ char *tmp = NULL;
+ char *buf = NULL;
+ int is_net=0;
+ int had_error = 0;
+ size_t buflen;
+
+ buflen = lstrlen(inbuf) + 1;
+ buf= (char *)heap_alloc(buflen);
+ (void)StringCbCopy(buf,buflen,inbuf);
+
+ if (!buf)
+ buf = "." ;
+ tmp = buf;
+ while(*tmp) {
+#ifdef DSPMBYTE
+ if (Ismbyte1(*tmp) && *(tmp + 1))
+ tmp ++;
+ else
+#endif DSPMBYTE
+ if (*tmp == '\\')
+ *tmp = '/';
+ tmp++;
+ }
+ /*
+ * paths like / confuse NT because it looks like a UNC name
+ * when we append "\*" -amol
+ */
+ if (*(tmp -1) == '/')
+ *(tmp -1) = 0;
+
+ buflen = lstrlen(buf) + 4;
+ tmp= (char *)heap_alloc(buflen);
+
+ if ( (buf[0] == '/') && (buf[1] != '/') ) {
+ (void)StringCbPrintf(tmp,buflen, "%c:%s*",
+ 'A' + (_getdrive()-1),buf);
+ }
+ else if ( (buf[0] == '/') && (buf[1] == '/') ){
+ is_net = 1;
+ (void)StringCbPrintf(tmp,buflen,"%s",buf);
+ }
+ else {
+ (void)StringCbPrintf(tmp,buflen,"%s/*",buf);
+ }
+
+ dptr = (DIR *)heap_alloc(sizeof(DIR));
+ dptr->dd_fd = INVALID_HANDLE_VALUE;
+ if (!dptr){
+ errno = ENOMEM;
+ had_error =1;
+ goto done;
+ }
+
+ if (is_net){
+ dptr->dd_fd = open_enum(tmp,&fdata);
+ dptr->flags = IS_NET;
+ }
+ if (dptr->dd_fd == INVALID_HANDLE_VALUE){
+ (void)StringCbPrintf(tmp,buflen,"%s/*",buf);
+ dptr->flags = 0;
+ dptr->dd_fd = FindFirstFile(tmp,&fdata);
+ }
+ if (dptr->dd_fd == INVALID_HANDLE_VALUE){
+ if (GetLastError() == ERROR_DIRECTORY)
+ errno = ENOTDIR;
+ else
+ errno = ENOENT;
+
+ had_error =1;
+ goto done;
+ }
+ memset(dptr->orig_dir_name,0,sizeof(dptr->orig_dir_name));
+ memcpy(dptr->orig_dir_name,tmp,lstrlen(tmp));
+
+ dptr->dd_loc = 0;
+ dptr->dd_size = fdata.nFileSizeLow;
+ dptr->dd_buf = (struct dirent *)heap_alloc(sizeof(struct dirent));
+ if (!dptr->dd_buf){
+ errno = ENOMEM;
+ had_error=1;
+ goto done;
+ }
+ (dptr->dd_buf)->d_ino = inode++;
+ (dptr->dd_buf)->d_off = 0;
+ (dptr->dd_buf)->d_reclen = 0;
+ if (lstrcmpi(fdata.cFileName,".") ){
+ //dptr->dd_buf->d_name[0] = '.';
+ memcpy((dptr->dd_buf)->d_name,".",2);
+ dptr->flags |= IS_ROOT;
+ }
+ else
+ memcpy((dptr->dd_buf)->d_name,fdata.cFileName,MAX_PATH);
+
+done:
+ if(tmp)
+ heap_free(tmp);
+ if(had_error) {
+ heap_free(dptr);
+ dptr = NULL;
+ }
+
+ return dptr;
+}
+int closedir(DIR *dptr){
+
+ if (!dptr)
+ return 0;
+ if (dptr->flags & IS_NET) {
+ close_enum(dptr);
+ }
+ else
+ FindClose(dptr->dd_fd);
+ heap_free(dptr->dd_buf);
+ heap_free(dptr);
+ return 0;
+}
+void rewinddir(DIR *dptr) {
+
+ HANDLE hfind;
+ WIN32_FIND_DATA fdata;
+ char *tmp = dptr->orig_dir_name;
+
+ if (!dptr) return;
+
+ if (dptr->flags & IS_NET) {
+ hfind = open_enum(tmp,&fdata);
+ close_enum(dptr);
+ dptr->dd_fd = hfind;
+ }
+ else {
+ hfind = FindFirstFile(tmp,&fdata);
+ assert(hfind != INVALID_HANDLE_VALUE);
+ FindClose(dptr->dd_fd);
+ dptr->dd_fd = hfind;
+ }
+ dptr->dd_size = fdata.nFileSizeLow;
+ (dptr->dd_buf)->d_ino = inode++;
+ (dptr->dd_buf)->d_off = 0;
+ (dptr->dd_buf)->d_reclen = 0;
+ memcpy((dptr->dd_buf)->d_name,fdata.cFileName,MAX_PATH);
+ return;
+}
+struct dirent *readdir(DIR *dir) {
+
+ WIN32_FIND_DATA fdata = {0};
+ HANDLE hfind;
+ char *tmp ;
+
+ if (!dir)
+ return NULL;
+
+ if (dir->flags & IS_NET) {
+ if(enum_next_share(dir)<0)
+ return NULL;
+ }
+ // special hack for root (which does not have . or ..)
+ else if (dir->flags & IS_ROOT) {
+ tmp= dir->orig_dir_name;
+ hfind = FindFirstFile(tmp,&fdata);
+ FindClose(dir->dd_fd);
+ dir->dd_fd = hfind;
+ dir->dd_size = fdata.nFileSizeLow;
+ (dir->dd_buf)->d_ino = inode++;
+ (dir->dd_buf)->d_off = 0;
+ (dir->dd_buf)->d_reclen = 0;
+ memcpy((dir->dd_buf)->d_name,fdata.cFileName,MAX_PATH);
+ dir->flags &= ~IS_ROOT;
+ return dir->dd_buf;
+
+ }
+ if(!(dir->flags & IS_NET) && !FindNextFile(dir->dd_fd,&fdata) ){
+ return NULL;
+ }
+ (dir->dd_buf)->d_ino = inode++;
+ (dir->dd_buf)->d_off = 0;
+ (dir->dd_buf)->d_reclen = 0;
+ if (! (dir->flags & IS_NET))
+ memcpy((dir->dd_buf)->d_name,fdata.cFileName,MAX_PATH);
+
+ return dir->dd_buf;
+
+}
+
+// Support for treating share names as directories
+// -amol 5/28/97
+static int ginited = 0;
+static HMODULE hmpr;
+
+typedef DWORD (__stdcall *open_fn)(DWORD,DWORD,DWORD,NETRESOURCE *, HANDLE*);
+typedef DWORD (__stdcall *close_fn)( HANDLE);
+typedef DWORD (__stdcall *enum_fn)( HANDLE,DWORD * ,void *,DWORD*);
+
+
+static open_fn p_WNetOpenEnum;
+static close_fn p_WNetCloseEnum;
+static enum_fn p_WNetEnumResource;
+
+HANDLE open_enum(char *server, WIN32_FIND_DATA *fdata) {
+
+ NETRESOURCE netres;
+ HANDLE henum;
+ unsigned long ret;
+ char *ptr;
+ int slashes;
+
+ nethandle_t *hnet;
+
+ ptr = server;
+ slashes = 0;
+
+ while(*ptr) {
+ if (*ptr == '/') {
+ *ptr = '\\';
+ slashes++;
+ }
+ ptr++;
+ }
+
+ if (!ginited) {
+ hmpr = LoadLibrary("MPR.DLL");
+ if (!hmpr)
+ return INVALID_HANDLE_VALUE;
+
+ p_WNetOpenEnum = (open_fn)GetProcAddress(hmpr,"WNetOpenEnumA");
+ p_WNetCloseEnum = (close_fn)GetProcAddress(hmpr,"WNetCloseEnum");
+ p_WNetEnumResource = (enum_fn)GetProcAddress(hmpr,"WNetEnumResourceA");
+
+ if (!p_WNetOpenEnum || !p_WNetCloseEnum || !p_WNetEnumResource)
+ return INVALID_HANDLE_VALUE;
+ ginited = 1;
+ }
+ if (slashes > 2)
+ return INVALID_HANDLE_VALUE;
+
+ memset(fdata,0,sizeof(WIN32_FIND_DATA));
+ fdata->cFileName[0] = '.';
+
+ netres.dwScope = RESOURCE_GLOBALNET;
+ netres.dwType = RESOURCETYPE_ANY;
+ netres.lpRemoteName = server;
+ netres.lpProvider = NULL;
+ netres.dwUsage = 0;
+
+ ret = p_WNetOpenEnum(RESOURCE_GLOBALNET,RESOURCETYPE_ANY,0,
+ &netres,&henum);
+ if (ret != NO_ERROR)
+ return INVALID_HANDLE_VALUE;
+
+ hnet = heap_alloc(sizeof(nethandle_t));
+ hnet->netres = heap_alloc(1024);/*FIXBUF*/
+ hnet->henum = henum;
+
+
+ return (HANDLE)hnet;
+
+}
+void close_enum(DIR*dptr) {
+ nethandle_t *hnet;
+
+ hnet = (nethandle_t*)(dptr->dd_fd);
+
+ heap_free(hnet->netres);
+ p_WNetCloseEnum(hnet->henum);
+ heap_free(hnet);
+}
+int enum_next_share(DIR *dir) {
+ nethandle_t *hnet;
+ char *tmp,*p1;
+ HANDLE henum;
+ DWORD count, breq,ret;
+
+ hnet = (nethandle_t*)(dir->dd_fd);
+ henum = hnet->henum;
+ count = 1;
+ breq = 1024;
+
+ ret = p_WNetEnumResource(henum, &count,hnet->netres,&breq);
+ if (ret != NO_ERROR)
+ return -1;
+
+ tmp = ((NETRESOURCE*)hnet->netres)->lpRemoteName;
+ p1 = &tmp[2];
+#ifdef DSPMBYTE
+ for (; *p1 != '\\'; p1 ++)
+ if (Ismbyte1(*p1) && *(p1 + 1))
+ p1 ++;
+#else /* DSPMBYTE */
+ while(*p1++ != '\\');
+#endif /* DSPMBYTE */
+
+ memcpy( (dir->dd_buf)->d_name, p1, lstrlen(p1)+1);
+
+ dir->dd_size = 0;
+
+ return 0;
+}
diff --git a/win32/dirent.h b/win32/dirent.h
new file mode 100644
index 000000000000..95fb8b38dd5a
--- /dev/null
+++ b/win32/dirent.h
@@ -0,0 +1,72 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/dirent.h,v 1.6 2006/03/03 22:08:45 amold Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * dirent.h
+ * directory interface functions. Sort of like dirent functions on unix.
+ * -amol
+ *
+ */
+#ifndef DIRENT_H
+#define DIRENT_H
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#define heap_alloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))
+#define heap_free(p) HeapFree(GetProcessHeap(),0,(p))
+#define heap_realloc(p,s) HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(p),(s))
+
+#define NAME_MAX MAX_PATH
+
+#define IS_ROOT 0x01
+#define IS_NET 0x02
+
+struct dirent {
+ long d_ino;
+ int d_off;
+ unsigned short d_reclen;
+ char d_name[NAME_MAX+1];
+};
+
+typedef struct {
+ HANDLE dd_fd;
+ int dd_loc;
+ int dd_size;
+ int flags;
+ char orig_dir_name[NAME_MAX +1];
+ struct dirent *dd_buf;
+}DIR;
+
+DIR *opendir(const char*);
+struct dirent *readdir(DIR*);
+int closedir(DIR*);
+void rewinddir(DIR*);
+#endif DIRENT_H
diff --git a/win32/example.tcshrc b/win32/example.tcshrc
new file mode 100644
index 000000000000..bb3b52d023b7
--- /dev/null
+++ b/win32/example.tcshrc
@@ -0,0 +1,211 @@
+#set verbose
+# set environmental variables
+ setenv EDITOR vi.exe
+ setenv PAGER c:/bin/less
+# setenv DISPLAY unix:0
+ setenv LESS "-B -c -h4 -i -M -q -x4 -G"
+ setenv SHELL C:/bin/tcsh.exe
+if ($?PROCESSOR_ARCHITECTURE) then
+ setenv USER $USERNAME
+ setenv LOGNAME $USER
+ setenv HOSTNAME $COMPUTERNAME
+endif
+
+umask 077
+if (! $?prompt) then # Everything else is interactive
+ exit(0)
+endif
+
+#tcsh-specific stuff
+if ($?tcsh) then
+# bindkey -v
+ set autolist
+ set listlinks
+ set pushdtohome
+ set visiblebell
+
+ set ellipsis
+ set rmstar
+# set prompt='%{f9%}%/%{gg%}(%{f2%}%?%{gg%})\>'
+if ($?TERM) then
+ if ($TERM == "emacs") then
+ set prompt='%/\>'
+ else
+ set prompt='%{f9%}%c03%{gg%}\>'
+ set prompt3 = '%{fc%}Correct to %R ?(y|n|e)%{gg%} '
+ endif
+else
+ set prompt='%{f9%}%c03%{gg%}\>'
+ set prompt3 = '%{fc%}Correct to %R ?(y|n|e)%{gg%} '
+endif
+
+ if ($?loginsh) then
+ set correct=all
+ set savedirs=100
+ set autocorrect
+ endif
+
+# set printexitvalue
+ set complete=igncase
+
+ complete which 'p/*/c/'
+ complete where 'p/*/c/'
+ complete start 'p/*/c/'
+ complete cd 'p/1/d/'
+ complete pushd 'p/1/d/'
+ complete popd 'p/1/d/'
+ complete tar 'n/-tvf/t:*.tar/' 'n/-xvf/t:*.tar/'
+ complete winhlp32 'p/*/f:*.HLP/'
+ complete pkunzip 'p/*/f:*.{ZIP,zip}/'
+ complete pkzip 'p/*/f:*.{zip,ZIP}/'
+ complete nmake 'p/*/f:*.MAK/'
+ complete bindkey 'p/*/b/'
+ complete set 'p/*/v/'
+ complete unset 'p/*/v/'
+
+# complex completions
+
+set noglob
+ complete gzip c/--/"(stdout to-stdout decompress uncompress \
+ force help list license no-name quiet recurse \
+ suffix test verbose version fast best)"/ \
+ c/-/"(c d f h l L n q r S t v V 1 2 3 4 5 6 7 8 9 -)"/\
+ n/{-S,--suffix}/x:'<file_name_suffix>'/ \
+ n/{-d,--{de,un}compress}/f:*.{gz,Z,z,zip,taz,tgz}/ \
+ N/{-d,--{de,un}compress}/f:*.{gz,Z,z,zip,taz,tgz}/ \
+ n/*/f:^*.{gz,Z,z,zip,taz,tgz}/
+ complete {gunzip,ungzip} c/--/"(stdout to-stdout force help list license \
+ no-name quiet recurse suffix test verbose version)"/ \
+ c/-/"(c f h l L n q r S t v V -)"/ \
+ n/{-S,--suffix}/x:'<file_name_suffix>'/ \
+ n/*/f:*.{gz,Z,z,zip,taz,tgz}/
+ complete mv c/--/"(backup force interactive update verbose suffix \
+ version-control help version)"/ \
+ c/-/"(b f i u v S V -)"/ \
+ n/{-S,--suffix}/x:'<suffix>'/ \
+ n/{-V,--version-control}/"(t numbered nil existing \
+ never simple)"/ n/-/f/ N/-/d/ p/1/f/ p/2/d/ n/*/f/
+ complete cp c/--/"(archive backup no-dereference force interactive \
+ link preserve symbolic-link update verbose parents \
+ one-file-system recursive suffix version-control help \
+ version)"/ c/-/"(a b d f i l p r s u v x P R S V -)"/ \
+ n/-*r/d/ n/{-S,--suffix}/x:'<suffix>'/ \
+ n/{-V,--version-control}/"(t numbered nil existing \
+ never simple)"/ n/-/f/ N/-/d/ p/1/f/ p/2/d/ n/*/f/
+
+
+ complete net p/1/"(accounts computer config continue file group \
+ help helpmsg localgroup name pause print send session \
+ share start statistics stop time use user view)"/ \
+ n/config/"(server workstation)"/ \
+ n/help/"(accounts computer config continue file group \
+ help helpmsg localgroup name pause print send session \
+ share start statistics stop time use user view)"/ \
+ n/view/"( \\server1 \\server2 )"/ \
+ n/\*/"( \\server1\share1 \\server2\share2 )"/
+
+ complete cl c@-@"(O G F C D E P U u I X v Z ? c H J nologo T V \
+ w W Y M L link)"@ \
+ n@-link@F:d:/lang/msdev/lib@ \
+ c/-O/"(1 2 a b d g i p s t w x y)"/ \
+ c/-G/"(3 4 5 B d r z e s f y h X)"/ \
+ c/-F/"(a A d e m o p r R)"/ \
+ c/-Z/"(i 7 d p a e g l z)"/ \
+ c/-M/"(T D L)"/ \
+ n@*@f:*.{c,C,cpp,CPP}@
+unset noglob
+#end completions
+
+ bindkey -b ^W backward-delete-word
+ bindkey -b ^U backward-kill-line
+ bindkey -b ^R complete-word-fwd
+ bindkey -b M-g list-glob
+ bindkey -b M-* expand-glob
+ bindkey -b M-v expand-variables
+ bindkey -b M-w normalize-command
+ bindkey -b M-/ which-command
+ bindkey -b M-r i-search-back
+ bindkey -b M-s i-search-fwd
+
+# bindkey -b C-I complete-word-fwd
+
+# NT specific bindkey extensions
+ bindkey -b N-up up-history
+ bindkey -b N-down down-history
+ bindkey -b N-right forward-char
+ bindkey -b N-left backward-char
+ bindkey -b N-del delete-char
+ bindkey -b N-ins overwrite-mode
+ bindkey -b N-1 which-command
+ bindkey -b N-2 expand-history
+ bindkey -b N-3 complete-word-raw
+ bindkey -b N-home beginning-of-line
+ bindkey -b N-end end-of-line
+
+#csh stuff
+else
+ set sedstr = "s:/[^/]*/[^/]*/[^/]*/::"
+ set prompt="`echo $cwd | sed -e 's:/[^/]*/[^/]*/[^/]*/::'`>"
+ alias cd ' cd \!*; set prompt=`echo $cwd | sed -e "$sedstr"`\>'
+ alias pushd ' pushd \!*; set prompt=`echo $cwd | sed -e "$sedstr"`\>'
+ alias popd ' popd \!*; set prompt=`echo $cwd | sed -e "$sedstr"`\>'
+endif
+
+#common to tcsh and csh
+
+
+
+if (! $?PATH_DONE) then
+set path=($path c:/gnubin .)
+setenv PATH_DONE 1
+endif
+
+set notify
+set cdpath=( C:/ D:/ )#E:/ H:/samples )
+set noclobber
+set filec
+set history=(1000)
+#"%h %T %{a2%}%R%{gg%}\n")
+#set histdup=all
+set savehist=(200 merge)
+set ignoreeof
+set fignore =(.obj .pdb .bsc .ilk .idb .OBJ .PDB .BSC .ILK .IDB)
+
+set NTlamepathfix
+eval `dircolors`
+unalias v d ls vdir dir
+
+alias ls ls-F
+alias lc ls $LS_OPTIONS
+alias h history
+#alias cwdcmd 'title `echo $cwd`'
+
+#
+# use the win32gnu utils for the following. or the win32sdk ones if you prefer.
+# PLEASE don't alias them to the posix utils in the reskit..
+#
+alias rm c:/gnubin/rm.exe -i
+alias rd c:/gnubin/rmdir.exe
+alias md c:/gnubin/mkdir.exe
+alias mv C:/bin/mv.exe -i
+alias cp C:/bin/cp.exe -i
+alias pwd 'echo $cwd'
+#
+alias env printenv
+alias net NET.EXE # avoid spelling correction to "set"
+alias cl CL.EXE # avoid spelling correction to "cp"
+alias word c:/apps/winword/winword/winword.exe
+alias excel e:/apps/excel/Excel/Excel.exe
+#alias telnet qvtnet32
+alias emacs c:/bin/emacs.csh
+alias gemacs c:/bin/gemacs.csh #gui emacs
+alias eshell c:/bin/eshell.csh
+alias helpcommand winhlp32
+alias benvcmd start cmd /k benv.cmd
+alias benv source c:/bin/razzle.csh
+
+alias use c:/bin/netuse.csh
+alias unuse c:/bin/netunuse.csh
+
+alias unsave unset savehist savedirs
+
diff --git a/win32/fork.c b/win32/fork.c
new file mode 100644
index 000000000000..d173e7ce0422
--- /dev/null
+++ b/win32/fork.c
@@ -0,0 +1,614 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/fork.c,v 1.11 2008/08/31 14:09:01 amold Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * The fork() here is based on the ideas used by cygwin
+ * -amol
+ *
+ */
+
+/*
+ * _M_ALPHA changes by Mark Tucker
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <fcntl.h>
+#include <io.h>
+#include <stdlib.h>
+#include <setjmp.h>
+#include <ntport.h>
+#include "forkdata.h"
+#include "sh.h"
+
+#pragma intrinsic("memcpy", "memset","memcmp")
+#pragma warning(push,3) // forget about W4 here
+
+typedef unsigned long u_long;
+typedef void *ptr_t;
+typedef unsigned char U_char;
+typedef unsigned int U_int;
+typedef unsigned short U_short;
+typedef unsigned long U_long;
+
+
+static void stack_probe(void *ptr) ;
+/*static void heap_init(void);*/
+BOOL CreateWow64Events(DWORD , HANDLE *, HANDLE *, BOOL);
+
+//
+// This is exported from the user program.
+// It must return 0 for no error !!!!
+extern int fork_copy_user_mem(HANDLE );
+
+/*
+ * Apparently , visual c++ on the alpha does not place the
+ * fork data contiguously. To work around that, Mark created
+ * this structure (see forkdata.h)
+ * -amol
+ */
+ForkData gForkData = {0,0,0,0,0,{0},0,0,0};
+
+
+#ifdef _M_IX86
+
+u_long _old_exr = 0; // Saved exception registration for longjmp
+
+#endif // _M_ALPHA
+/*
+ * This hack is an attempt at getting to the exception registration
+ * in an architecture-independent way. It's critical for longjmp in a
+ * code using __try/__except blocks. Microsoft Visual C++ does a global
+ * unwind during a longjmp, and that can cause havoc if the exception
+ * registration stored in longjmp is lower(address wise, indicating a jump
+ * from below of the stack upward.) in the stack than the current
+ * registration (returned by NtCurrentTeb).
+ *
+ * This works with VC++, because that's all I have. With other compilers,
+ * there might be minimal changes required, depending on where the
+ * exception registration record is stored in the longjmp structure.
+ *
+ * -amol 2/6/97
+ */
+
+NT_TIB * (* myNtCurrentTeb)(void);
+
+#define GETEXCEPTIONREGIST() (((NT_TIB*)get_teb())->ExceptionList)
+#define GETSTACKBASE() (((NT_TIB*)get_teb())->StackBase)
+
+
+
+static NT_TIB *the_tib;
+
+#if !defined(_M_IA64) && !defined(_M_AMD64)
+void *get_teb(void) {
+
+
+ if (the_tib)
+ return the_tib;
+
+ myNtCurrentTeb = (void*)GetProcAddress(LoadLibrary("ntdll.dll"),
+ "NtCurrentTeb");
+ if (!myNtCurrentTeb)
+ return NULL;
+ the_tib = myNtCurrentTeb();
+
+ if (the_tib == NULL)
+ abort();
+ return the_tib;
+}
+#else
+#define get_teb NtCurrentTeb
+#endif _M_IA64
+
+void set_stackbase(void*ptr){
+ GETSTACKBASE() = ptr;
+}
+/*
+ * This must be called by the application as the first thing it does.
+ * -amol 2/6/97
+ *
+ * Well, maybe not the FIRST..
+ * -amol 11/10/97
+ */
+
+extern BOOL bIsWow64Process;
+
+int fork_init(void) {
+
+
+ //heap_init(); Now called as the very first thing in silly_entry().
+
+ if (__forked) {
+
+
+ // stack_probe probes out a decent-sized stack for the child,
+ // since initially it has a very small stack (1 page).
+ //
+
+ /* not needed since default commit is set to 0.5MB in
+ * makefile.win32
+ *
+ * stack_probe((char *)__fork_stack_end - 64);
+ */
+
+ //
+ // Save the old Exception registration record and jump
+ // off the cliff.
+ //
+#ifdef _M_IX86
+ _old_exr = __fork_context[6];
+ __fork_context[6] =(int)GETEXCEPTIONREGIST();//tmp;
+#endif _M_ALPHA
+ //
+ // Whee !
+ longjmp(__fork_context,1);
+ }
+
+ return 0;
+}
+int fork(void) {
+
+ size_t rc;
+ size_t stacksize;
+ char modname[512];/*FIXBUF*/
+ HANDLE hProc,hThread, hArray[2];
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ SECURITY_ATTRIBUTES sa;
+ DWORD dwCreationflags;
+ unsigned int priority;
+ HANDLE h64Parent,h64Child;
+
+#ifndef _M_ALPHA
+ unsigned long fork_stack_end;
+#endif _M_ALPHA
+
+ __fork_stack_begin =GETSTACKBASE();
+
+#ifndef _M_ALPHA
+ __fork_stack_end = &fork_stack_end;
+#else
+ __fork_stack_end = (unsigned long *)__asm("mov $sp, $0");
+#endif /*_M_ALPHA*/
+
+ h64Parent = h64Child = NULL;
+ //
+ // Create two inheritable events
+ //
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor =0;
+ sa.bInheritHandle = TRUE;
+ if (!__hforkchild)
+ __hforkchild = CreateEvent(&sa,TRUE,FALSE,NULL);
+ if (!__hforkparent)
+ __hforkparent = CreateEvent(&sa,TRUE,FALSE,NULL);
+
+ rc = setjmp(__fork_context);
+
+ if (rc) { // child
+#ifdef _M_IX86
+ //
+ // Restore old registration
+ // -amol 2/2/97
+ GETEXCEPTIONREGIST() = (struct _EXCEPTION_REGISTRATION_RECORD*)_old_exr;
+#endif // _M_ALPHA
+ SetEvent(__hforkchild);
+
+ dprintf("Child ready to rumble\n");
+ if(WaitForSingleObject(__hforkparent,FORK_TIMEOUT) != WAIT_OBJECT_0)
+ ExitProcess(0xFFFF);
+
+ CloseHandle(__hforkchild);
+ CloseHandle(__hforkparent);
+ __hforkchild = __hforkparent=0;
+
+ //__asm { int 3};
+ restore_fds();
+
+ STR_environ = blk2short(environ);
+ environ = short2blk(STR_environ); /* So that we can free it */
+
+ return 0;
+ }
+ copy_fds();
+ memset(&si,0,sizeof(si));
+ si.cb= sizeof(si);
+
+ /*
+ * This f!@#!@% function returns the old value even if the std handles
+ * have been closed.
+ * Skip this step, since we know tcsh will do the right thing later.
+ *
+ si.hStdInput= GetStdHandle(STD_INPUT_HANDLE);
+ si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+ */
+
+ if (!GetModuleFileName(GetModuleHandle(NULL),modname,512) ) {
+ rc = GetLastError();
+ return -1;
+ }
+ dwCreationflags = GetPriorityClass(GetCurrentProcess());
+ priority = GetThreadPriority(GetCurrentThread());
+ rc = CreateProcess(NULL,
+ modname,
+ NULL,
+ NULL,
+ TRUE,
+ CREATE_SUSPENDED | dwCreationflags,
+ NULL,
+ NULL,
+ &si,
+ &pi);
+ if (!rc) {
+ rc = GetLastError();
+ return -1;
+ }
+
+ ResetEvent(__hforkchild);
+ ResetEvent(__hforkparent);
+
+ hProc = pi.hProcess;
+ hThread = pi.hThread;
+
+
+ __forked=1;
+ /*
+ * Usage of events in the wow64 case:
+ *
+ * h64Parent : initially non-signalled
+ * h64Child : initially non-signalled
+ *
+ * 1. Create the events, resume the child thread.
+ * 2. Child opens h64Parent to see if it is a child process in wow64
+ * 3. Child opens and sets h64Child to tell parent it's running. (This
+ * step is needed because we can't copy to a process created in the
+ * suspended state on wow64.)
+ * 4. Copy gForkData and then set h64Parent. This tells the child
+ * that the parameters in the structure are trustworthy.
+ * 5. Wait for h64Child so that we know the child has created the stack
+ * in dynamic memory.
+ *
+ * The rest of the fork hack should now proceed as in x86
+ *
+ */
+ if (bIsWow64Process) {
+
+ // allocate the heap for the child. this can be done even when
+ // the child is suspended.
+ // avoids inexplicable allocation failures in the child.
+ if (VirtualAllocEx(hProc,
+ __heap_base,
+ __heap_size,
+ MEM_RESERVE,
+ PAGE_READWRITE) == NULL) {
+ dprintf("virtual allocex failed %d\n",GetLastError());
+ goto error;
+ }
+ if (VirtualAllocEx(hProc,
+ __heap_base,
+ __heap_size,
+ MEM_COMMIT,
+ PAGE_READWRITE) == NULL) {
+ dprintf("virtual allocex2 failed %d\n",GetLastError());
+ goto error;
+ }
+
+ // Do NOT expect existing events
+ if (!CreateWow64Events(pi.dwProcessId,&h64Parent,&h64Child,FALSE)) {
+ goto error;
+ }
+ ResumeThread(hThread);
+
+ // wait for the child to tell us it is running
+ //if (WaitForSingleObject(h64Child,FORK_TIMEOUT) != WAIT_OBJECT_0) {
+ // rc = GetLastError();
+ // goto error;
+ //}
+ hArray[0] = h64Child;
+ hArray[1] = hProc;
+
+ if (WaitForMultipleObjects(2,hArray,FALSE,FORK_TIMEOUT) !=
+ WAIT_OBJECT_0){
+
+ rc = GetLastError();
+ goto error;
+ }
+
+ }
+ //
+ // Copy all the shared data
+ //
+ if (!WriteProcessMemory(hProc,&gForkData,&gForkData,
+ sizeof(ForkData),&rc)) {
+ goto error;
+ }
+ if (rc != sizeof(ForkData))
+ goto error;
+
+ if (!bIsWow64Process) {
+ rc = ResumeThread(hThread);
+ }
+ // in the wow64 case, the child will be waiting on h64parent again.
+ // set it, and then wait for h64child. This will mean the child has
+ // a stack set up at the right location.
+ else {
+ SetEvent(h64Parent);
+ hArray[0] = h64Child;
+ hArray[1] = hProc;
+
+ if (WaitForMultipleObjects(2,hArray,FALSE,FORK_TIMEOUT) !=
+ WAIT_OBJECT_0){
+
+ rc = GetLastError();
+ goto error;
+ }
+ CloseHandle(h64Parent);
+ CloseHandle(h64Child);
+ h64Parent = h64Child = NULL;
+ }
+
+ //
+ // Wait for the child to start and init itself.
+ // The timeout is so that we don't wait too long
+ //
+ hArray[0] = __hforkchild;
+ hArray[1] = hProc;
+
+ if (WaitForMultipleObjects(2,hArray,FALSE,FORK_TIMEOUT) != WAIT_OBJECT_0){
+
+ int err = GetLastError(); // For debugging purposes
+ dprintf("wait failed err %d\n",err);
+ goto error;
+ }
+
+ // Stop the child again and copy the stack and heap
+ //
+ SuspendThread(hThread);
+
+ if (!SetThreadPriority(hThread,priority) ) {
+ priority =GetLastError();
+ }
+
+ // stack
+ stacksize = (char*)__fork_stack_begin - (char*)__fork_stack_end;
+ if (!WriteProcessMemory(hProc,(char *)__fork_stack_end,
+ (char *)__fork_stack_end,
+ (u_long)stacksize,
+ &rc)){
+ goto error;
+ }
+ //
+ // copy heap itself
+ if (!WriteProcessMemory(hProc, (void*)__heap_base,(void*)__heap_base,
+ (DWORD)((char*)__heap_top-(char*)__heap_base),
+ &rc)){
+ goto error;
+ }
+
+ rc = fork_copy_user_mem(hProc);
+
+ if(rc) {
+ goto error;
+ }
+
+ // Release the child.
+ SetEvent(__hforkparent);
+ rc = ResumeThread(hThread);
+
+ __forked=0;
+ dprintf("forked process %d\n",pi.dwProcessId);
+ start_sigchild_thread(hProc,pi.dwProcessId);
+ close_copied_fds();
+
+ CloseHandle(hThread);
+ //
+ // return process id to parent.
+ return pi.dwProcessId;
+
+error:
+ __forked=0;
+ SetEvent(__hforkparent);
+ ResumeThread(hThread);
+ CloseHandle(hProc);
+ CloseHandle(hThread);
+ if (h64Parent) {
+ SetEvent(h64Parent); // don't let child block forever
+ CloseHandle(h64Parent);
+ }
+ if (h64Child)
+ CloseHandle(h64Child);
+ return -1;
+}
+#pragma optimize("",off)
+// The damn optimizer will remove the recursion, resulting in an infinite
+// loop. -amol 4/17/97
+void stack_probe (void *ptr) {
+ char buf[1000];
+ int x;
+
+ if (&x > (int *)ptr)
+ stack_probe(ptr);
+ (void)buf;
+}
+#pragma optimize("",on)
+//
+// This function basically reserves some heap space.
+// In the child it also commits the size committed in the parent.
+void heap_init(void) {
+
+ char * temp;
+ int err;
+ if (__forked) {
+ temp = (char *)VirtualAlloc((void*)__heap_base,__heap_size, MEM_RESERVE,
+ PAGE_READWRITE);
+ if (temp != (char*)__heap_base) {
+ if (!temp){
+ err = GetLastError();
+ if (bIsWow64Process)
+ ExitProcess(0);
+ abort();
+ }
+ else
+ __heap_base = temp;
+ }
+ if (!VirtualAlloc(__heap_base,(char*)__heap_top -(char*)__heap_base,
+ MEM_COMMIT,PAGE_READWRITE)){
+ err = GetLastError();
+ if (bIsWow64Process)
+ ExitProcess(0);
+ abort();
+ }
+ temp = (char*)__heap_base;
+ }
+ else {
+ SYSTEM_INFO sysinfo;
+ GetSystemInfo(&sysinfo);
+ __heap_size = sysinfo.dwPageSize * 1024;
+ __heap_base = VirtualAlloc(0 , __heap_size,MEM_RESERVE|MEM_TOP_DOWN,
+ PAGE_READWRITE);
+
+ if (__heap_base == 0) {
+ abort();
+ }
+
+ __heap_top = __heap_base;
+ }
+
+}
+//
+// Implementation of sbrk() for the fmalloc family
+//
+void * sbrk(int delta) {
+
+ void *retval;
+ void *old_top=__heap_top;
+ char *b = (char*)__heap_top;
+
+ if (delta == 0)
+ return __heap_top;
+ if (delta > 0) {
+
+ retval =VirtualAlloc((void*)__heap_top,delta,MEM_COMMIT,PAGE_READWRITE);
+
+ if (retval == 0 )
+ abort();
+
+ b += delta;
+ __heap_top = (void*)b;
+ }
+ else {
+ retval = VirtualAlloc((void*)((char*)__heap_top - delta),
+ delta,MEM_DECOMMIT, PAGE_READWRITE);
+
+ if (retval == 0)
+ abort();
+
+ b -= delta;
+ __heap_top = (void*)b;
+ }
+
+ return (void*) old_top;
+}
+/*
+ * Semantics of CreateWow64Events
+ *
+ * Try to open the events even if bOpenExisting is FALSE. This will help
+ * us detect name duplication.
+ *
+ * 1. If OpenEvent succeeds,and bOpenExisting is FALSE, fail.
+ *
+ * 2. If OpenEvent failed,and bOpenExisting is TRUE fail
+ *
+ * 3. else create the events anew
+ *
+ */
+#define TCSH_WOW64_PARENT_EVENT_NAME "tcsh-wow64-parent-event"
+#define TCSH_WOW64_CHILD_EVENT_NAME "tcsh-wow64-child-event"
+BOOL CreateWow64Events(DWORD pid, HANDLE *hParent, HANDLE *hChild,
+ BOOL bOpenExisting) {
+
+ SECURITY_ATTRIBUTES sa;
+ char parentname[256],childname[256];
+
+ *hParent = *hChild = NULL;
+
+ // make darn sure they're not inherited
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor =0;
+ sa.bInheritHandle = FALSE;
+ //
+
+#pragma warning(disable:4995)
+
+ // This event tells the child to hold for gForkData to be copied
+ wsprintfA(parentname, "Local\\%d-%s",pid, TCSH_WOW64_PARENT_EVENT_NAME);
+
+ wsprintfA(childname, "Local\\%d-%s",pid, TCSH_WOW64_CHILD_EVENT_NAME );
+
+#pragma warning(default:4995)
+
+ *hParent = OpenEvent(EVENT_ALL_ACCESS,FALSE, parentname);
+
+ if(*hParent) {
+ if (bOpenExisting == FALSE) { // didn't expect to be a child process
+ CloseHandle(*hParent);
+ *hParent = NULL;
+ return FALSE;
+ }
+
+ *hChild = OpenEvent(EVENT_ALL_ACCESS,FALSE, childname);
+ if (!*hChild) {
+ CloseHandle(*hParent);
+ *hParent = NULL;
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+ else { //event does not exist
+ if (bOpenExisting == TRUE)
+ return FALSE;
+ }
+
+ *hParent = CreateEvent(&sa,FALSE,FALSE,parentname);
+ if (!*hParent)
+ return FALSE;
+
+
+ *hChild = CreateEvent(&sa,FALSE,FALSE,childname);
+ if (!*hChild){
+ CloseHandle(*hParent);
+ *hParent = NULL;
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/win32/forkdata.h b/win32/forkdata.h
new file mode 100644
index 000000000000..5d3f30a37f4e
--- /dev/null
+++ b/win32/forkdata.h
@@ -0,0 +1,76 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/forkdata.h,v 1.4 2004/05/19 18:22:27 christos Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#ifndef FORK_DATA_H
+#define FORK_DATA_H
+
+#include <setjmp.h>
+
+/*
+ * This structure is copied by fork() to the child process. It
+ * contains variables of national importance
+ *
+ * Thanks to Mark Tucker for the idea. tcsh now finally works on
+ * alphas.
+ * -amol
+ */
+typedef struct _fork_data {
+ unsigned long _forked;
+ void *_fork_stack_begin;
+ void *_fork_stack_end;
+ unsigned long _heap_size;
+ HANDLE _hforkparent, _hforkchild;
+ void * _heap_base;
+ void * _heap_top;
+ jmp_buf _fork_context;
+} ForkData;
+
+#define __forked gForkData._forked
+#define __fork_stack_begin gForkData._fork_stack_begin
+#define __fork_stack_end gForkData._fork_stack_end
+#define __hforkparent gForkData._hforkparent
+#define __hforkchild gForkData._hforkchild
+#define __fork_context gForkData._fork_context
+#define __heap_base gForkData._heap_base
+#define __heap_size gForkData._heap_size
+#define __heap_top gForkData._heap_top
+
+extern ForkData gForkData;
+
+#ifdef NTDBG
+#define FORK_TIMEOUT INFINITE
+#else
+#define FORK_TIMEOUT (50000)
+#endif /*!NTDBG */
+
+
+
+#endif FORK_DATA_H
diff --git a/win32/globals.c b/win32/globals.c
new file mode 100644
index 000000000000..7c5cc95b5217
--- /dev/null
+++ b/win32/globals.c
@@ -0,0 +1,222 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/globals.c,v 1.11 2008/09/10 20:34:21 amold Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * globals.c: The mem locations needed in the child are copied here.
+ * -amol
+ */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+#define STRSAFE_LIB
+#define STRSAFE_NO_CCH_FUNCTIONS
+#include <strsafe.h>
+
+extern unsigned long bookend1,bookend2;
+extern char **environ;
+
+#define IMAGE_SIZEOF_NT_OPTIONAL32_HEADER 224
+#define IMAGE_SIZEOF_NT_OPTIONAL64_HEADER 240
+
+#ifdef _WIN64
+#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL64_HEADER
+#else
+#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL32_HEADER
+#endif
+
+
+#undef dprintf
+void
+dprintf(char *format, ...)
+{ /* } */
+ va_list vl;
+ char putbuf[2048];
+ DWORD err;
+
+ err = GetLastError();
+ {
+ va_start(vl, format);
+#pragma warning(disable:4995)
+ wvsprintf(putbuf,format, vl);
+#pragma warning(default:4995)
+ va_end(vl);
+ OutputDebugString(putbuf);
+ }
+ SetLastError(err);
+}
+/*
+ * This function is called by fork(). The process must copy
+ * whatever memory is needed in the child. hproc is a handle
+ * to the child process
+ *
+ */
+int fork_copy_user_mem(HANDLE hproc) {
+
+ SIZE_T bytes,rc;
+ SIZE_T size;
+ void *low = &bookend1, *high= &bookend2;
+
+ if(&bookend1 > &bookend2) {
+ low = &bookend2;
+ high = &bookend1;
+ }
+
+ size =(char*)high - (char*)low;
+
+
+ rc =WriteProcessMemory(hproc,low,low, (DWORD)size, &bytes);
+
+ if (!rc) {
+ rc = GetLastError();
+ return -1;
+ }
+ if (size != bytes) {
+ //dprintf("size %d , wrote %d\n",size,bytes);
+ }
+ return 0;
+}
+/*
+ * Inspired by Microsoft KB article ID: Q90493
+ *
+ * returns 0 (false) if app is non-gui, 1 otherwise.
+*/
+#include <winnt.h>
+#include <ntport.h>
+
+__inline BOOL wait_for_io(HANDLE hi, OVERLAPPED *pO) {
+
+ DWORD bytes = 0;
+ if(GetLastError() != ERROR_IO_PENDING)
+ {
+ return FALSE;
+ }
+
+ return GetOverlappedResult(hi,pO,&bytes,TRUE);
+}
+#define CHECK_IO(h,o) if(!wait_for_io(h,o)) {goto done;}
+
+int is_gui(char *exename) {
+
+ HANDLE hImage;
+
+ DWORD bytes;
+ OVERLAPPED overlap;
+
+ ULONG ntSignature;
+
+ struct DosHeader{
+ IMAGE_DOS_HEADER doshdr;
+ DWORD extra[16];
+ };
+
+ struct DosHeader dh;
+ IMAGE_OPTIONAL_HEADER optionalhdr;
+
+ int retCode = 0;
+
+ memset(&overlap,0,sizeof(overlap));
+
+
+ hImage = CreateFile(exename, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL| FILE_FLAG_OVERLAPPED, NULL);
+ if (INVALID_HANDLE_VALUE == hImage) {
+ return 0;
+ }
+
+ ReadFile(hImage, &dh, sizeof(struct DosHeader), &bytes,&overlap);
+ CHECK_IO(hImage,&overlap);
+
+
+ if (IMAGE_DOS_SIGNATURE != dh.doshdr.e_magic) {
+ goto done;
+ }
+
+ // read from the coffheaderoffset;
+ overlap.Offset = dh.doshdr.e_lfanew;
+
+ ReadFile(hImage, &ntSignature, sizeof(ULONG), &bytes,&overlap);
+ CHECK_IO(hImage,&overlap);
+
+ if (IMAGE_NT_SIGNATURE != ntSignature) {
+ goto done;
+ }
+ overlap.Offset = dh.doshdr.e_lfanew + sizeof(ULONG) +
+ sizeof(IMAGE_FILE_HEADER);
+
+ ReadFile(hImage, &optionalhdr,IMAGE_SIZEOF_NT_OPTIONAL_HEADER, &bytes,&overlap);
+ CHECK_IO(hImage,&overlap);
+
+ if (optionalhdr.Subsystem ==IMAGE_SUBSYSTEM_WINDOWS_GUI)
+ retCode = 1;
+done:
+ CloseHandle(hImage);
+ return retCode;
+}
+int is_9x_gui(char *prog) {
+
+ char *progpath;
+ DWORD dwret;
+ char *pathbuf;
+ char *pext;
+
+ pathbuf=heap_alloc(MAX_PATH+1);
+ if(!pathbuf)
+ return 0;
+
+ progpath=heap_alloc((MAX_PATH<<1)+1);
+ if(!progpath)
+ return 0;
+
+ if (GetEnvironmentVariable("PATH",pathbuf,MAX_PATH) ==0) {
+ goto failed;
+ }
+
+ pathbuf[MAX_PATH]=0;
+
+ dwret = SearchPath(pathbuf,prog,".EXE",MAX_PATH<<1,progpath,&pext);
+
+ if ( (dwret == 0) || (dwret > (MAX_PATH<<1) ) )
+ goto failed;
+
+ dprintf("progpath is %s\n",progpath);
+ dwret = is_gui(progpath);
+
+ heap_free(pathbuf);
+ heap_free(progpath);
+
+ return dwret;
+
+failed:
+ heap_free(pathbuf);
+ heap_free(progpath);
+ return 0;
+
+
+}
diff --git a/win32/io.c b/win32/io.c
new file mode 100644
index 000000000000..0124f1b2a028
--- /dev/null
+++ b/win32/io.c
@@ -0,0 +1,479 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/io.c,v 1.9 2006/04/13 00:59:02 amold Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * io.c
+ * wrapper functions for some i/o routines.
+ * -amol
+ *
+ */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <memory.h>
+#include <errno.h>
+#include "sh.h"
+#include "ntport.h"
+#include "signal.h"
+
+
+#pragma warning(disable:4127) //conditional expr is constant
+
+#define CR 0x0d
+
+
+extern void make_err_str(unsigned int ,char *,int ) ;
+extern void generic_handler(int);
+extern int console_write(HANDLE,unsigned char*,int);
+
+int consoleread(HANDLE , unsigned char * ,size_t ) ;
+
+INPUT_RECORD girec[2048];
+
+unsigned short __nt_want_vcode=0,__nt_vcode=0;
+HANDLE __h_con_alarm=0;
+HANDLE __h_con_int=0;
+HANDLE __h_con_hup=0;
+
+extern int NoNLSRebind;
+
+extern int OLDSTD, SHIN;
+/*
+ * force_read: Forces a ReadFile, instead of ReadConsole
+ *
+ */
+int force_read(int fd, unsigned char * buf, size_t howmany) {
+ DWORD numread=0,err=0;
+ HANDLE hRead ;
+
+
+ hRead= (HANDLE)__nt_get_osfhandle(fd);
+ if (hRead == INVALID_HANDLE_VALUE) {
+ return 0;
+ }
+again:
+ if (!ReadFile(hRead, buf,(DWORD)howmany,&numread, NULL ) ){
+ err = GetLastError();
+ switch(err) {
+ case ERROR_IO_PENDING:
+ break;
+ case ERROR_ACCESS_DENIED:
+ case ERROR_INVALID_HANDLE:
+ errno = EBADF;
+ return -1;
+ break;
+ case ERROR_HANDLE_EOF:
+ case ERROR_BROKEN_PIPE:
+ errno = 0;
+ return 0;
+ default:
+ errno = EBADF;
+ return 0;
+ }
+ }
+ if (numread == 1 && buf[0] == CR)
+ goto again;
+ return numread;
+}
+int nt_read(int fd, unsigned char * buf, size_t howmany) {
+
+ DWORD numread=0,err=0;
+ HANDLE hRead ;
+ DWORD ftype;
+ //
+
+ hRead= (HANDLE)__nt_get_osfhandle(fd);
+ if (hRead == INVALID_HANDLE_VALUE) {
+ return 0;
+ }
+
+ ftype = GetFileType(hRead);
+
+
+ if ((ftype == FILE_TYPE_CHAR) /*&& (fd != OLDSTD) && (fd != SHIN)*/)
+ return consoleread(hRead,buf,howmany);
+again:
+ if (!ReadFile(hRead, buf,(DWORD)howmany,&numread, NULL ) ){
+ err = GetLastError();
+ switch(err) {
+ case ERROR_IO_PENDING:
+ break;
+ case ERROR_ACCESS_DENIED:
+ case ERROR_INVALID_HANDLE:
+ errno = EBADF;
+ return -1;
+ break;
+ case ERROR_HANDLE_EOF:
+ case ERROR_BROKEN_PIPE:
+ errno = 0;
+ return 0;
+ default:
+ errno = EBADF;
+ return 0;
+ }
+ }
+ if (numread) {
+ if (buf[numread-1] == CR)
+ numread--;
+ if (numread == 0)
+ goto again;
+ }
+ return numread;
+}
+
+/* color-ls patches from TAGA nayuta (nayuta@is.s.u-tokyo.ac.jp) */
+#ifdef COLOR_LS_F
+
+int nt_write_(int , const unsigned char * , size_t );
+int nt_write(int fd, const unsigned char * buf, size_t howmany) {
+ static unsigned char color_buf[256];
+ static char len = 0;
+
+ ssize_t i;
+ ssize_t start = 0;
+ int rc,wrote = 0;
+
+ if (!isatty(fd) || (varval(STRcolor) == NULL))
+ return nt_write_(fd, buf, howmany);
+
+ for (i = 0; i < howmany; i++) {
+ switch (len) {
+ case 0:
+ if (buf[i] == '\x1b') {
+ color_buf[len++] = buf[i];
+ if (0 < i - start){
+ if ((rc=nt_write_(fd, &(buf[start]), i - start)) <0)
+ return -1;
+ else
+ wrote += rc;
+ }
+ start = -1;
+ }
+ break;
+
+ case 1:
+ if (buf[i] != '[')
+ goto set_color;
+ color_buf[len++] = buf[i];
+ break;
+
+ default:
+ if (buf[i] == 'm' || (!isdigit(buf[i]) && buf[i] != ';'))
+ goto set_color;
+ color_buf[len++] = buf[i];
+ break;
+
+ case sizeof(color_buf) - 1:
+set_color:
+ color_buf[len] = '\0';
+ set_attributes(color_buf);
+ len = 0;
+ start = i + 1;
+ break;
+ }
+ }
+
+ if (0 < i - start && 0 <= start) {
+ if ((rc=nt_write_(fd, &(buf[start]), i - start)) < 0)
+ return -1;
+ else
+ wrote += rc;
+ }
+ return wrote;
+}
+int nt_write_(int fd, const unsigned char * buf, size_t howmany)
+#else /* if !COLOR_LS_F */
+int nt_write(int fd, const unsigned char * buf, size_t howmany)
+#endif /* COLOR_LS_F */
+{
+ int bytes_rtn,err;
+ HANDLE hout;
+
+
+ hout = (HANDLE)__nt_get_osfhandle(fd);
+ /*
+ if (isatty(fd))
+ ;// return console_write(hout,buf,howmany);
+ */
+
+ if(!WriteFile(hout, buf,(DWORD)howmany,(ULONG*)&bytes_rtn,
+ NULL)){
+ err = GetLastError();
+ switch(err) {
+ case ERROR_ACCESS_DENIED:
+ case ERROR_INVALID_HANDLE:
+ errno = EBADF;
+ return -1;
+ break;
+ case ERROR_BROKEN_PIPE:
+ errno = EPIPE;
+ return -1;
+ default:
+ errno = EBADF;
+ return -1;
+ }
+
+ }
+ return bytes_rtn?bytes_rtn:-1;
+
+}
+
+#define IS_CTRL_COMBO(a) ( (a) & ( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED) )
+#define IS_ALT_COMBO(a) ( /*(a) &*/ alt_pressed )
+#define IS_SHIFT_COMBO(a) ( (a) & SHIFT_PRESSED)
+
+int consoleread(HANDLE hInput, unsigned char * buf,size_t howmany) {
+
+ INPUT_RECORD *irec = NULL;
+ DWORD numread,controlkey,i;
+ WORD vcode;
+ unsigned char ch;
+ int rc;
+ size_t where=0;
+ int alt_pressed = 0,memfree=0;
+ HANDLE hevents[4];
+ static int pre_ch = -1;
+
+ if (0 <= pre_ch) {
+ buf[0] = (unsigned char)pre_ch;
+ pre_ch = -1;
+ return 1;
+ }
+
+ howmany /= 2; // [ALT + KEY] is expanded ESC KEY, so we need more buffer
+ if (howmany == 0)
+ howmany = 1;
+
+ if (howmany > 2048){
+ irec = heap_alloc(howmany*sizeof(INPUT_RECORD));
+ memfree=1;
+ }
+ else
+ irec = &(girec[0]);
+ if (!irec){
+ errno = ENOMEM;
+ return -1;
+ }
+ while(1) {
+ hevents[0] = __h_con_alarm;
+ hevents[1] = __h_con_int;
+ hevents[2] = __h_con_hup;
+ hevents[3] = hInput;
+ rc = WaitForMultipleObjects(sizeof(hevents)/sizeof(hevents[0]),
+ hevents,FALSE,INFINITE);
+ if (rc == WAIT_OBJECT_0) {
+ generic_handler(SIGALRM);
+ }
+ if (rc == (WAIT_OBJECT_0 +1) ) {
+ errno = EINTR;
+ generic_handler(SIGINT);
+ break;
+ }
+ if (rc == (WAIT_OBJECT_0 +2) ) {
+ errno = EINTR;
+ generic_handler(SIGHUP);
+ break;
+ }
+ rc = ReadConsoleInput(hInput,irec,(DWORD)howmany,&numread);
+ if (!rc) {
+ rc = GetLastError();
+ switch (rc) {
+ case ERROR_INVALID_HANDLE:
+ case ERROR_ACCESS_DENIED:
+ errno = EBADF;
+ break;
+ }
+ if (memfree)
+ heap_free(irec);
+ return -1;
+ }
+ __nt_vcode=0;
+ for(i=0;i<numread;i++) {
+ switch(irec[i].EventType) {
+ case KEY_EVENT:
+ if (irec[i].Event.KeyEvent.bKeyDown) {
+ vcode=(irec[i].Event.KeyEvent.wVirtualKeyCode);
+ ch=(irec[i].Event.KeyEvent.uChar.AsciiChar);
+ controlkey=(irec[i].Event.KeyEvent.dwControlKeyState);
+ if (controlkey & LEFT_ALT_PRESSED)
+ alt_pressed=1;
+ else if (controlkey & RIGHT_ALT_PRESSED){
+ if (NoNLSRebind)
+ alt_pressed=1;
+ }
+
+ if (__nt_want_vcode != 1)
+ goto skippy;
+
+ if (vcode >= VK_F1 && vcode <= VK_F24) {
+
+ __nt_vcode=NT_SPECIFIC_BINDING_OFFSET ;
+ __nt_vcode += (vcode- VK_F1) + SINGLE_KEY_OFFSET;
+
+ if (IS_CTRL_COMBO(controlkey))
+ __nt_vcode += CTRL_KEY_OFFSET;
+
+ else if (IS_ALT_COMBO(controlkey))
+ __nt_vcode += ALT_KEY_OFFSET;
+ else if (IS_SHIFT_COMBO(controlkey))
+ __nt_vcode += SHIFT_KEY_OFFSET;
+
+ __nt_want_vcode=2;
+
+ return 1;
+ }
+ else if (vcode>= VK_PRIOR && vcode <= VK_DOWN) {
+
+ __nt_vcode = NT_SPECIFIC_BINDING_OFFSET ;
+ __nt_vcode += KEYPAD_MAPPING_BEGIN;
+ __nt_vcode += (vcode -VK_PRIOR);
+
+ __nt_vcode += SINGLE_KEY_OFFSET ;
+
+ if (IS_CTRL_COMBO(controlkey))
+ __nt_vcode += CTRL_KEY_OFFSET;
+
+ else if (IS_ALT_COMBO(controlkey))
+ __nt_vcode += ALT_KEY_OFFSET;
+ else if (IS_SHIFT_COMBO(controlkey))
+ __nt_vcode += SHIFT_KEY_OFFSET;
+
+ __nt_want_vcode=2;
+ return 1;
+ }
+ else if (vcode == VK_INSERT) {
+ __nt_vcode = NT_SPECIFIC_BINDING_OFFSET ;
+ __nt_vcode += INS_DEL_MAPPING_BEGIN;
+
+ if (IS_CTRL_COMBO(controlkey))
+ __nt_vcode += CTRL_KEY_OFFSET;
+
+ else if (IS_ALT_COMBO(controlkey))
+ __nt_vcode += ALT_KEY_OFFSET;
+
+ else if (IS_SHIFT_COMBO(controlkey))
+ __nt_vcode += SHIFT_KEY_OFFSET;
+
+ __nt_want_vcode=2;
+ return 1;
+ }
+ else if (vcode == VK_DELETE) {
+ __nt_vcode = NT_SPECIFIC_BINDING_OFFSET ;
+ __nt_vcode += INS_DEL_MAPPING_BEGIN + 1;
+
+ if (IS_CTRL_COMBO(controlkey))
+ __nt_vcode += CTRL_KEY_OFFSET;
+
+ else if (IS_ALT_COMBO(controlkey))
+ __nt_vcode += ALT_KEY_OFFSET;
+
+ else if (IS_SHIFT_COMBO(controlkey))
+ __nt_vcode += SHIFT_KEY_OFFSET;
+
+ __nt_want_vcode=2;
+
+ return 1;
+ }
+skippy:
+ switch(vcode) {
+ case VK_ESCAPE:
+ buf[where++]='\033';
+ break;
+ default:
+ if(ch ){
+ /*
+ * Looks like win95 has a spurious
+ * newline left over
+ */
+ if (gdwPlatform ==
+ VER_PLATFORM_WIN32_WINDOWS &&
+ ch == '\r'){
+ DWORD bread;
+ (void)ReadFile(hInput,&ch,1,&bread,NULL);
+ }
+ /* patch from TAGA nayuta */
+ if ( NoNLSRebind &&
+ (ch == ' ' || ch == '@') &&
+ IS_CTRL_COMBO(controlkey)
+ /*(controlkey & LEFT_CTRL_PRESSED ||
+ controlkey & RIGHT_CTRL_PRESSED)*/
+ )
+ ch = 0;
+ if (alt_pressed) {
+#ifdef DSPMBYTE
+ buf[where++] = '\033';
+ if (howmany == 1)
+ pre_ch = ch;
+ else
+ buf[where++] = ch;
+#else /* !DSPMBYTE */
+ buf[where++] = ch | 0200;
+#endif /* !DSPMBYTE */
+ }
+ else
+ buf[where++] = ch;
+ }
+ break;
+ }
+
+ alt_pressed=0;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (where == 0)
+ continue;
+ if (howmany < where) // avoid trashing memory. -amol 4/16/97
+ buf[where]=0;
+ break;
+ }
+ if (memfree)
+ heap_free(irec);
+ if (!where)
+ return -1;
+ return (int)(where );
+}
+int console_write(HANDLE hout, unsigned char * buf,int howmany) {
+ int bytes,rc;
+
+ bytes = -1;
+
+ rc = WriteConsole(hout,buf,howmany,(DWORD*)&bytes,NULL);
+ if (!rc) {
+ errno = EBADF;
+ bytes = -1;
+ rc = GetLastError();
+ }
+
+ return bytes;
+}
diff --git a/win32/msg/Makefile b/win32/msg/Makefile
new file mode 100644
index 000000000000..bfe1e3541a11
--- /dev/null
+++ b/win32/msg/Makefile
@@ -0,0 +1,49 @@
+!if "$(PROCESSOR_ARCHITECTURE)" == "x86"
+MACHINE = ix86
+!else if "$(PROCESSOR_ARCHITECTURE)" == "ALPHA"
+MACHINE = alpha
+!else #Assume win9x
+MACHINE = ix86
+!endif
+LIBS= libcmt.lib kernel32.lib
+
+all: tcshfr.dll tcshc.dll tcshde.dll tcshsp.dll tcshja.dll tcsh-it.dll
+
+stubdll.obj:stubdll.c
+ cl -W3 -MT -c stubdll.c
+
+tcshgr.dll: tcshgr.res stubdll.obj
+ link -machine:$(MACHINE) -nodefaultlib $(LIBS) tcshgr.res stubdll.obj \
+ -out:tcshgr.dll
+
+tcshfr.dll: tcshfr.res stubdll.obj
+ link -machine:$(MACHINE) -dll -nodefaultlib $(LIBS) tcshfr.res stubdll.obj \
+ -out:tcshfr.dll
+
+tcshde.dll: tcshde.res stubdll.obj
+ link -machine:$(MACHINE) -dll -nodefaultlib $(LIBS) tcshde.res stubdll.obj \
+ -out:tcshde.dll
+
+tcshsp.dll: tcshsp.res stubdll.obj
+ link -machine:$(MACHINE) -dll -nodefaultlib $(LIBS) tcshsp.res stubdll.obj \
+ -out:tcshsp.dll
+
+tcsh-it.dll: tcsh-it.res stubdll.obj
+ link -machine:$(MACHINE) -dll -nodefaultlib $(LIBS) tcsh-it.res stubdll.obj\
+ -out:tcsh-it.dll
+
+tcshja.dll: tcshja.res stubdll.obj
+ link -machine:$(MACHINE) -dll -nodefaultlib $(LIBS) tcshja.res stubdll.obj \
+ -out:tcshja.dll
+
+tcshc.dll: tcshc.res stubdll.obj
+ link -machine:$(MACHINE) -dll -nodefaultlib $(LIBS) tcshc.res stubdll.obj \
+ -out:tcshc.dll
+
+test.exe: test.obj
+ link test.obj user32.lib -out:test.exe
+clean:
+ -del *.obj *.res
+
+cleanall: clean
+ -del *.dll *.exe
diff --git a/win32/msg/makerc.pl b/win32/msg/makerc.pl
new file mode 100644
index 000000000000..39805f7c3914
--- /dev/null
+++ b/win32/msg/makerc.pl
@@ -0,0 +1,43 @@
+# This script converts a tcsh nls file into a format suitable for compiling
+# with RC and stubdll.c. This gives us a stringtable resource in the DLL
+# which can be loaded at startup for tcsh messages.
+#
+# Depending on the languages, the final output may take some tweaking. I have
+# not been able to get Greek to compile in the resource compiler. French,
+# German, and the C locale seem to work.
+#
+# This prints to stdout, so redirect to appropriate place.
+#
+# The alogrithm is simple :
+#
+# String ID = set number * 10,000 + message number
+#
+# This is because we cannot have two messages with the same id.
+#
+# -amol 9/15/96
+#
+#
+print "#include <windows.h>\n";
+print "STRINGTABLE DISCARDABLE\n";
+print "BEGIN\n";
+
+for($i=1; $i <32;$i++) {
+ $filename = "set" . $i;
+
+ open(CURRSET,$filename);
+
+ while(<CURRSET>) {
+ chop $_;
+ if (/^\$/) {
+ print "//" . $_ . "\n";
+ }
+ else {
+# comment following for greek ???
+ s/\"/\"\"/g;
+ ($num,$line)= split(' ',$_,2);
+ print ($i*10000 + $num);
+ print " \"" . $line . "\"\n";
+ }
+ }
+}
+print "END\n"
diff --git a/win32/msg/makercjp.pl b/win32/msg/makercjp.pl
new file mode 100644
index 000000000000..39694a850a4f
--- /dev/null
+++ b/win32/msg/makercjp.pl
@@ -0,0 +1,31 @@
+# This script is almost as same as makerc.pl except that the coding of
+# nls files is converted from euc_japan to shift_jis by nkf.exe
+#
+# this is for japanese nls files
+#
+# 1998/09/23 - nayuta
+
+print "#include <windows.h>\n";
+print "STRINGTABLE DISCARDABLE\n";
+print "BEGIN\n";
+
+for($i=1; $i <32;$i++) {
+ $filename = "set" . $i;
+
+ open(CURRSET,"nkf -E -s $filename |");
+
+ while(<CURRSET>) {
+ chop $_;
+ if (/^\$/) {
+ print "//" . $_ . "\n";
+ }
+ else {
+# comment following for greek ???
+ s/\"/\"\"/g;
+ ($num,$line)= split(' ',$_,2);
+ print ($i*10000 + $num);
+ print " \"" . $line . "\"\n";
+ }
+ }
+}
+print "END\n"
diff --git a/win32/msg/makercrc.pl b/win32/msg/makercrc.pl
new file mode 100644
index 000000000000..d75dea79ee5c
--- /dev/null
+++ b/win32/msg/makercrc.pl
@@ -0,0 +1,35 @@
+# This script converts a .tcshrc file into a format suitable for compiling
+# with RC and stubdll.c. This gives us a stringtable resource in the DLL
+# which can be loaded with the loadresource builtin
+#
+# This prints to stdout, so redirect to appropriate place.
+#
+# The alogrithm is simple :
+#
+# String ID = 666 + line number
+#
+# -amol 3/28/01
+#
+#
+print "#include <windows.h>\n";
+print "STRINGTABLE DISCARDABLE\n";
+print "BEGIN\n";
+
+$filename = $ARGV[0];
+
+open(RCFILE,$filename);
+
+$i = 666;
+while(<RCFILE>) {
+ chop $_;
+ next if (/^#/) ;
+ next if (/^$/);
+
+ s/\"/\"\"/g;
+# print $_;
+
+ print ($i);
+ print " \"" . $_ . "\"\n";
+ $i++;
+}
+print "END\n"
diff --git a/win32/msg/stubdll.c b/win32/msg/stubdll.c
new file mode 100644
index 000000000000..aadadb79237d
--- /dev/null
+++ b/win32/msg/stubdll.c
@@ -0,0 +1,7 @@
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+BOOL WINAPI DllEntryPoint(HINSTANCE hdll,DWORD dwreason,LPVOID ignore) {
+
+ return 1;
+}
diff --git a/win32/msg/test.c b/win32/msg/test.c
new file mode 100644
index 000000000000..d47d5933812b
--- /dev/null
+++ b/win32/msg/test.c
@@ -0,0 +1,33 @@
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdio.h>
+#include <locale.h>
+
+void main(int argc, char **argv) {
+
+ HINSTANCE hinst;
+ WCHAR buffer[128];
+ unsigned char winbuf[128],oembuf[128];
+ unsigned int number;
+
+ if (argc <3)
+ return;
+
+ hinst = LoadLibrary(argv[1]);
+
+ number = atoi(argv[2]);
+ printf("Load String returns %i\n",
+ LoadStringW(hinst, number, buffer, sizeof(buffer)));
+
+ WideCharToMultiByte(CP_OEMCP,
+ 0,
+ buffer,
+ -1,
+ winbuf,
+ 128,
+ NULL,
+ NULL);
+
+ CharToOem(winbuf,oembuf);
+ printf("oem: %s\n",oembuf);
+}
diff --git a/win32/nt.bind.c b/win32/nt.bind.c
new file mode 100644
index 000000000000..17e5a75910ca
--- /dev/null
+++ b/win32/nt.bind.c
@@ -0,0 +1,1351 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/nt.bind.c,v 1.6 2006/03/05 08:59:36 amold Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include "sh.h"
+#include "ed.h"
+#include "ed.defns.h"
+
+
+KEYCMD CcEmacsMap[] = {
+ /* keymap table, each index into above tbl; should be
+ (256+extra NT bindings)*sizeof(KEYCMD) bytes long */
+
+ F_SET_MARK, /* ^@ */
+ F_TOBEG, /* ^A */
+ F_CHARBACK, /* ^B */
+ F_TTY_INT, /* ^C */
+ F_DELNEXT_LIST_EOF, /* ^D */
+ F_TOEND, /* ^E */
+ F_CHARFWD, /* ^F */
+ F_UNASSIGNED, /* ^G */
+ F_DELPREV, /* ^H */
+ F_COMPLETE, /* ^I */
+ F_NEWLINE, /* ^J */
+ F_KILLEND, /* ^K */
+ F_CLEARDISP, /* ^L */
+ F_NEWLINE, /* ^M */
+ F_DOWN_HIST, /* ^N */
+ F_TTY_FLUSHO, /* ^O */
+ F_UP_HIST, /* ^P */
+ F_TTY_STARTO, /* ^Q */
+ F_REDISP, /* ^R */
+ F_TTY_STOPO, /* ^S */
+ F_CHARSWITCH, /* ^T */
+ F_KILLALL, /* ^U */
+ F_QUOTE, /* ^V */
+ F_KILLREGION, /* ^W */
+ F_XKEY, /* ^X */
+ F_YANK_KILL, /* ^Y */
+ F_TTY_TSUSP, /* ^Z */
+ F_METANEXT, /* ^[ */
+ F_TTY_QUIT, /* ^\ */
+ F_TTY_DSUSP, /* ^] */
+ F_UNASSIGNED, /* ^^ */
+ F_UNASSIGNED, /* ^_ */
+ F_INSERT, /* SPACE */
+ F_INSERT, /* ! */
+ F_INSERT, /* " */
+ F_INSERT, /* # */
+ F_INSERT, /* $ */
+ F_INSERT, /* % */
+ F_INSERT, /* & */
+ F_INSERT, /* ' */
+ F_INSERT, /* ( */
+ F_INSERT, /* ) */
+ F_INSERT, /* * */
+ F_INSERT, /* + */
+ F_INSERT, /* , */
+ F_INSERT, /* - */
+ F_INSERT, /* . */
+ F_INSERT, /* / */
+ F_DIGIT, /* 0 */
+ F_DIGIT, /* 1 */
+ F_DIGIT, /* 2 */
+ F_DIGIT, /* 3 */
+ F_DIGIT, /* 4 */
+ F_DIGIT, /* 5 */
+ F_DIGIT, /* 6 */
+ F_DIGIT, /* 7 */
+ F_DIGIT, /* 8 */
+ F_DIGIT, /* 9 */
+ F_INSERT, /* : */
+ F_INSERT, /* ; */
+ F_INSERT, /* < */
+ F_INSERT, /* = */
+ F_INSERT, /* > */
+ F_INSERT, /* ? */
+ F_INSERT, /* @ */
+ F_INSERT, /* A */
+ F_INSERT, /* B */
+ F_INSERT, /* C */
+ F_INSERT, /* D */
+ F_INSERT, /* E */
+ F_INSERT, /* F */
+ F_INSERT, /* G */
+ F_INSERT, /* H */
+ F_INSERT, /* I */
+ F_INSERT, /* J */
+ F_INSERT, /* K */
+ F_INSERT, /* L */
+ F_INSERT, /* M */
+ F_INSERT, /* N */
+ F_INSERT, /* O */
+ F_INSERT, /* P */
+ F_INSERT, /* Q */
+ F_INSERT, /* R */
+ F_INSERT, /* S */
+ F_INSERT, /* T */
+ F_INSERT, /* U */
+ F_INSERT, /* V */
+ F_INSERT, /* W */
+ F_INSERT, /* X */
+ F_INSERT, /* Y */
+ F_INSERT, /* Z */
+ F_INSERT, /* [ */
+ F_INSERT, /* \ */
+ F_INSERT, /* ] */
+ F_INSERT, /* ^ */
+ F_INSERT, /* _ */
+ F_INSERT, /* ` */
+ F_INSERT, /* a */
+ F_INSERT, /* b */
+ F_INSERT, /* c */
+ F_INSERT, /* d */
+ F_INSERT, /* e */
+ F_INSERT, /* f */
+ F_INSERT, /* g */
+ F_INSERT, /* h */
+ F_INSERT, /* i */
+ F_INSERT, /* j */
+ F_INSERT, /* k */
+ F_INSERT, /* l */
+ F_INSERT, /* m */
+ F_INSERT, /* n */
+ F_INSERT, /* o */
+ F_INSERT, /* p */
+ F_INSERT, /* q */
+ F_INSERT, /* r */
+ F_INSERT, /* s */
+ F_INSERT, /* t */
+ F_INSERT, /* u */
+ F_INSERT, /* v */
+ F_INSERT, /* w */
+ F_INSERT, /* x */
+ F_INSERT, /* y */
+ F_INSERT, /* z */
+ F_INSERT, /* { */
+ F_INSERT, /* | */
+ F_INSERT, /* } */
+ F_INSERT, /* ~ */
+ F_DELPREV, /* ^? */
+ F_UNASSIGNED, /* M-^@ */
+ F_UNASSIGNED, /* M-^A */
+ F_UNASSIGNED, /* M-^B */
+ F_UNASSIGNED, /* M-^C */
+ F_LIST_CHOICES, /* M-^D */
+ F_UNASSIGNED, /* M-^E */
+ F_UNASSIGNED, /* M-^F */
+ F_UNASSIGNED, /* M-^G */
+ F_DELWORDPREV, /* M-^H */
+ F_COMPLETE, /* M-^I */
+ F_UNASSIGNED, /* M-^J */
+ F_UNASSIGNED, /* M-^K */
+ F_CLEARDISP, /* M-^L */
+ F_UNASSIGNED, /* M-^M */
+ F_UNASSIGNED, /* M-^N */
+ F_UNASSIGNED, /* M-^O */
+ F_UNASSIGNED, /* M-^P */
+ F_UNASSIGNED, /* M-^Q */
+ F_UNASSIGNED, /* M-^R */
+ F_UNASSIGNED, /* M-^S */
+ F_UNASSIGNED, /* M-^T */
+ F_UNASSIGNED, /* M-^U */
+ F_UNASSIGNED, /* M-^V */
+ F_UNASSIGNED, /* M-^W */
+ F_UNASSIGNED, /* M-^X */
+ F_UNASSIGNED, /* M-^Y */
+ F_RUN_FG_EDITOR, /* M-^Z */
+ F_COMPLETE, /* M-^[ */
+ F_UNASSIGNED, /* M-^\ */
+ F_UNASSIGNED, /* M-^] */
+ F_UNASSIGNED, /* M-^^ */
+ F_COPYPREV, /* M-^_ */
+ F_EXPAND_HISTORY, /* M-SPACE */
+ F_EXPAND_HISTORY, /* M-! */
+ F_UNASSIGNED, /* M-" */
+ F_UNASSIGNED, /* M-# */
+ F_CORRECT_L, /* M-$ */
+ F_UNASSIGNED, /* M-% */
+ F_UNASSIGNED, /* M-& */
+ F_UNASSIGNED, /* M-' */
+ F_UNASSIGNED, /* M-( */
+ F_UNASSIGNED, /* M-) */
+ F_UNASSIGNED, /* M-* */
+ F_UNASSIGNED, /* M-+ */
+ F_UNASSIGNED, /* M-, */
+ F_UNASSIGNED, /* M-- */
+ F_UNASSIGNED, /* M-. */
+ F_DABBREV_EXPAND, /* M-/ */
+ F_ARGDIGIT, /* M-0 */
+ F_ARGDIGIT, /* M-1 */
+ F_ARGDIGIT, /* M-2 */
+ F_ARGDIGIT, /* M-3 */
+ F_ARGDIGIT, /* M-4 */
+ F_ARGDIGIT, /* M-5 */
+ F_ARGDIGIT, /* M-6 */
+ F_ARGDIGIT, /* M-7 */
+ F_ARGDIGIT, /* M-8 */
+ F_ARGDIGIT, /* M-9 */
+ F_UNASSIGNED, /* M-: */
+ F_UNASSIGNED, /* M-; */
+ F_UNASSIGNED, /* M-< */
+ F_UNASSIGNED, /* M-= */
+ F_UNASSIGNED, /* M-> */
+ F_WHICH, /* M-? */
+ F_UNASSIGNED, /* M-@ */
+ F_UNASSIGNED, /* M-A */
+ F_WORDBACK, /* M-B */
+ F_CASECAPITAL, /* M-C */
+ F_DELWORDNEXT, /* M-D */
+ F_UNASSIGNED, /* M-E */
+ F_WORDFWD, /* M-F */
+ F_UNASSIGNED, /* M-G */
+ F_HELPME, /* M-H */
+ F_UNASSIGNED, /* M-I */
+ F_UNASSIGNED, /* M-J */
+ F_UNASSIGNED, /* M-K */
+ F_CASELOWER, /* M-L */
+ F_UNASSIGNED, /* M-M */
+ F_DOWN_SEARCH_HIST, /* M-N */
+ F_XKEY, /* M-O *//* extended key esc PWP Mar 88 */
+ F_UP_SEARCH_HIST, /* M-P */
+ F_UNASSIGNED, /* M-Q */
+ F_TOGGLE_HIST, /* M-R */
+ F_CORRECT, /* M-S */
+ F_UNASSIGNED, /* M-T */
+ F_CASEUPPER, /* M-U */
+ F_UNASSIGNED, /* M-V */
+ F_COPYREGION, /* M-W */
+ F_UNASSIGNED, /* M-X */
+ F_UNASSIGNED, /* M-Y */
+ F_UNASSIGNED, /* M-Z */
+ F_XKEY, /* M-[ *//* extended key esc -mf Oct 87 */
+ F_UNASSIGNED, /* M-\ */
+ F_UNASSIGNED, /* M-] */
+ F_UNASSIGNED, /* M-^ */
+ F_LAST_ITEM, /* M-_ */
+ F_UNASSIGNED, /* M-` */
+ F_UNASSIGNED, /* M-a */
+ F_WORDBACK, /* M-b */
+ F_CASECAPITAL, /* M-c */
+ F_DELWORDNEXT, /* M-d */
+ F_UNASSIGNED, /* M-e */
+ F_WORDFWD, /* M-f */
+ F_UNASSIGNED, /* M-g */
+ F_HELPME, /* M-h */
+ F_UNASSIGNED, /* M-i */
+ F_UNASSIGNED, /* M-j */
+ F_UNASSIGNED, /* M-k */
+ F_CASELOWER, /* M-l */
+ F_UNASSIGNED, /* M-m */
+ F_DOWN_SEARCH_HIST, /* M-n */
+ F_UNASSIGNED, /* M-o */
+ F_UP_SEARCH_HIST, /* M-p */
+ F_UNASSIGNED, /* M-q */
+ F_TOGGLE_HIST, /* M-r */
+ F_CORRECT, /* M-s */
+ F_UNASSIGNED, /* M-t */
+ F_CASEUPPER, /* M-u */
+ F_UNASSIGNED, /* M-v */
+ F_COPYREGION, /* M-w */
+ F_UNASSIGNED, /* M-x */
+ F_UNASSIGNED, /* M-y */
+ F_UNASSIGNED, /* M-z */
+ F_UNASSIGNED, /* M-{ */
+ F_UNASSIGNED, /* M-| */
+ F_UNASSIGNED, /* M-} */
+ F_UNASSIGNED, /* M-~ */
+ F_DELWORDPREV, /* M-^? */
+ /* Extra keys begin here */
+ F_UNASSIGNED, /* f-1 */
+ F_UNASSIGNED, /* f-2 */
+ F_UNASSIGNED, /* f-3 */
+ F_UNASSIGNED, /* f-4 */
+ F_UNASSIGNED, /* f-5 */
+ F_UNASSIGNED, /* f-6 */
+ F_UNASSIGNED, /* f-7 */
+ F_UNASSIGNED, /* f-8 */
+ F_UNASSIGNED, /* f-9 */
+ F_UNASSIGNED, /* f-10 */
+ F_UNASSIGNED, /* f-11 */
+ F_UNASSIGNED, /* f-12 */
+ F_UNASSIGNED, /* f-13 */
+ F_UNASSIGNED, /* f-14 */
+ F_UNASSIGNED, /* f-15 */
+ F_UNASSIGNED, /* f-16 */
+ F_UNASSIGNED, /* f-17 */
+ F_UNASSIGNED, /* f-18 */
+ F_UNASSIGNED, /* f-19 */
+ F_UNASSIGNED, /* f-20 */
+ F_UNASSIGNED, /* f-21 */
+ F_UNASSIGNED, /* f-22 */
+ F_UNASSIGNED, /* f-23 */
+ F_UNASSIGNED, /* f-24 */
+ F_UNASSIGNED, /* PgUp */
+ F_UNASSIGNED, /* PgDn */
+ F_UNASSIGNED, /* end */
+ F_UNASSIGNED, /* home */
+ F_UNASSIGNED, /* LEFT */
+ F_UNASSIGNED, /* UP */
+ F_UNASSIGNED, /* RIGHT */
+ F_UNASSIGNED, /* DOWN */
+ F_UNASSIGNED, /* INS */
+ F_UNASSIGNED, /* DEL */
+ /* ctrl key mappings */
+ F_UNASSIGNED, /* f-1 */
+ F_UNASSIGNED, /* f-2 */
+ F_UNASSIGNED, /* f-3 */
+ F_UNASSIGNED, /* f-4 */
+ F_UNASSIGNED, /* f-5 */
+ F_UNASSIGNED, /* f-6 */
+ F_UNASSIGNED, /* f-7 */
+ F_UNASSIGNED, /* f-8 */
+ F_UNASSIGNED, /* f-9 */
+ F_UNASSIGNED, /* f-10 */
+ F_UNASSIGNED, /* f-11 */
+ F_UNASSIGNED, /* f-12 */
+ F_UNASSIGNED, /* f-13 */
+ F_UNASSIGNED, /* f-14 */
+ F_UNASSIGNED, /* f-15 */
+ F_UNASSIGNED, /* f-16 */
+ F_UNASSIGNED, /* f-17 */
+ F_UNASSIGNED, /* f-18 */
+ F_UNASSIGNED, /* f-19 */
+ F_UNASSIGNED, /* f-20 */
+ F_UNASSIGNED, /* f-21 */
+ F_UNASSIGNED, /* f-22 */
+ F_UNASSIGNED, /* f-23 */
+ F_UNASSIGNED, /* f-24 */
+ F_UNASSIGNED, /* PgUp */
+ F_UNASSIGNED, /* PgDn */
+ F_UNASSIGNED, /* end */
+ F_UNASSIGNED, /* home */
+ F_UNASSIGNED, /* LEFT */
+ F_UNASSIGNED, /* UP */
+ F_UNASSIGNED, /* RIGHT */
+ F_UNASSIGNED, /* DOWN */
+ F_UNASSIGNED, /* INS */
+ F_UNASSIGNED, /* DEL */
+
+ /* alt key mappings */
+ F_UNASSIGNED, /* f-1 */
+ F_UNASSIGNED, /* f-2 */
+ F_UNASSIGNED, /* f-3 */
+ F_UNASSIGNED, /* f-4 */
+ F_UNASSIGNED, /* f-5 */
+ F_UNASSIGNED, /* f-6 */
+ F_UNASSIGNED, /* f-7 */
+ F_UNASSIGNED, /* f-8 */
+ F_UNASSIGNED, /* f-9 */
+ F_UNASSIGNED, /* f-10 */
+ F_UNASSIGNED, /* f-11 */
+ F_UNASSIGNED, /* f-12 */
+ F_UNASSIGNED, /* f-13 */
+ F_UNASSIGNED, /* f-14 */
+ F_UNASSIGNED, /* f-15 */
+ F_UNASSIGNED, /* f-16 */
+ F_UNASSIGNED, /* f-17 */
+ F_UNASSIGNED, /* f-18 */
+ F_UNASSIGNED, /* f-19 */
+ F_UNASSIGNED, /* f-20 */
+ F_UNASSIGNED, /* f-21 */
+ F_UNASSIGNED, /* f-22 */
+ F_UNASSIGNED, /* f-23 */
+ F_UNASSIGNED, /* f-24 */
+ F_UNASSIGNED, /* PgUp */
+ F_UNASSIGNED, /* PgDn */
+ F_UNASSIGNED, /* end */
+ F_UNASSIGNED, /* home */
+ F_UNASSIGNED, /* LEFT */
+ F_UNASSIGNED, /* UP */
+ F_UNASSIGNED, /* RIGHT */
+ F_UNASSIGNED, /* DOWN */
+ F_UNASSIGNED, /* INS */
+ F_UNASSIGNED, /* DEL */
+ /* shift key mappings */
+ F_UNASSIGNED, /* f-1 */
+ F_UNASSIGNED, /* f-2 */
+ F_UNASSIGNED, /* f-3 */
+ F_UNASSIGNED, /* f-4 */
+ F_UNASSIGNED, /* f-5 */
+ F_UNASSIGNED, /* f-6 */
+ F_UNASSIGNED, /* f-7 */
+ F_UNASSIGNED, /* f-8 */
+ F_UNASSIGNED, /* f-9 */
+ F_UNASSIGNED, /* f-10 */
+ F_UNASSIGNED, /* f-11 */
+ F_UNASSIGNED, /* f-12 */
+ F_UNASSIGNED, /* f-13 */
+ F_UNASSIGNED, /* f-14 */
+ F_UNASSIGNED, /* f-15 */
+ F_UNASSIGNED, /* f-16 */
+ F_UNASSIGNED, /* f-17 */
+ F_UNASSIGNED, /* f-18 */
+ F_UNASSIGNED, /* f-19 */
+ F_UNASSIGNED, /* f-20 */
+ F_UNASSIGNED, /* f-21 */
+ F_UNASSIGNED, /* f-22 */
+ F_UNASSIGNED, /* f-23 */
+ F_UNASSIGNED, /* f-24 */
+ F_UNASSIGNED, /* PgUp */
+ F_UNASSIGNED, /* PgDn */
+ F_UNASSIGNED, /* end */
+ F_UNASSIGNED, /* home */
+ F_UNASSIGNED, /* LEFT */
+ F_UNASSIGNED, /* UP */
+ F_UNASSIGNED, /* RIGHT */
+ F_UNASSIGNED, /* DOWN */
+ F_UNASSIGNED, /* INS */
+ F_UNASSIGNED /* DEL */
+};
+
+/*
+ * keymap table for vi. Each index into above tbl; should be
+ * 256 entries long. Vi mode uses a sticky-extend to do command mode:
+ * insert mode characters are in the normal keymap, and command mode
+ * in the extended keymap.
+ */
+KEYCMD CcViMap[] = {
+#ifdef KSHVI
+ F_UNASSIGNED, /* ^@ */
+ F_INSERT, /* ^A */
+ F_INSERT, /* ^B */
+ F_INSERT, /* ^C */
+ F_INSERT, /* ^D */
+ F_INSERT, /* ^E */
+ F_INSERT, /* ^F */
+ F_INSERT, /* ^G */
+ V_DELPREV, /* ^H */ /* BackSpace key */
+ F_COMPLETE, /* ^I */ /* Tab Key */
+ F_NEWLINE, /* ^J */
+ F_INSERT, /* ^K */
+ F_INSERT, /* ^L */
+ F_NEWLINE, /* ^M */
+ F_INSERT, /* ^N */
+ F_INSERT, /* ^O */
+ F_INSERT, /* ^P */
+ F_TTY_STARTO, /* ^Q */
+ F_INSERT, /* ^R */
+ F_INSERT, /* ^S */
+ F_INSERT, /* ^T */
+ F_INSERT, /* ^U */
+ F_QUOTE, /* ^V */
+ F_DELWORDPREV, /* ^W */ /* Only until start edit pos */
+ F_INSERT, /* ^X */
+ F_INSERT, /* ^Y */
+ F_INSERT, /* ^Z */
+ V_CMD_MODE, /* ^[ */ /* [ Esc ] key */
+ F_TTY_QUIT, /* ^\ */
+ F_INSERT, /* ^] */
+ F_INSERT, /* ^^ */
+ F_INSERT, /* ^_ */
+#else /* !KSHVI */
+ F_UNASSIGNED, /* ^@ */ /* NOTE: These mapping do NOT */
+ F_TOBEG, /* ^A */ /* Correspond well to the KSH */
+ F_CHARBACK, /* ^B */ /* VI editting assignments */
+ F_TTY_INT, /* ^C */ /* On the other hand they are */
+ F_LIST_EOF, /* ^D */ /* convenient any many people */
+ F_TOEND, /* ^E */ /* have gotten used to them */
+ F_CHARFWD, /* ^F */
+ F_LIST_GLOB, /* ^G */
+ F_DELPREV, /* ^H */ /* BackSpace key */
+ F_COMPLETE, /* ^I */ /* Tab Key */
+ F_NEWLINE, /* ^J */
+ F_KILLEND, /* ^K */
+ F_CLEARDISP, /* ^L */
+ F_NEWLINE, /* ^M */
+ F_DOWN_HIST, /* ^N */
+ F_TTY_FLUSHO, /* ^O */
+ F_UP_HIST, /* ^P */
+ F_TTY_STARTO, /* ^Q */
+ F_REDISP, /* ^R */
+ F_TTY_STOPO, /* ^S */
+ F_CHARSWITCH, /* ^T */
+ F_KILLBEG, /* ^U */
+ F_QUOTE, /* ^V */
+ F_DELWORDPREV, /* ^W */
+ F_EXPAND, /* ^X */
+ F_TTY_DSUSP, /* ^Y */
+ F_TTY_TSUSP, /* ^Z */
+ V_CMD_MODE, /* ^[ */
+ F_TTY_QUIT, /* ^\ */
+ F_UNASSIGNED, /* ^] */
+ F_UNASSIGNED, /* ^^ */
+ F_UNASSIGNED, /* ^_ */
+#endif /* KSHVI */
+ F_INSERT, /* SPACE */
+ F_INSERT, /* ! */
+ F_INSERT, /* " */
+ F_INSERT, /* # */
+ F_INSERT, /* $ */
+ F_INSERT, /* % */
+ F_INSERT, /* & */
+ F_INSERT, /* ' */
+ F_INSERT, /* ( */
+ F_INSERT, /* ) */
+ F_INSERT, /* * */
+ F_INSERT, /* + */
+ F_INSERT, /* , */
+ F_INSERT, /* - */
+ F_INSERT, /* . */
+ F_INSERT, /* / */
+ F_INSERT, /* 0 */
+ F_INSERT, /* 1 */
+ F_INSERT, /* 2 */
+ F_INSERT, /* 3 */
+ F_INSERT, /* 4 */
+ F_INSERT, /* 5 */
+ F_INSERT, /* 6 */
+ F_INSERT, /* 7 */
+ F_INSERT, /* 8 */
+ F_INSERT, /* 9 */
+ F_INSERT, /* : */
+ F_INSERT, /* ; */
+ F_INSERT, /* < */
+ F_INSERT, /* = */
+ F_INSERT, /* > */
+ F_INSERT, /* ? */
+ F_INSERT, /* @ */
+ F_INSERT, /* A */
+ F_INSERT, /* B */
+ F_INSERT, /* C */
+ F_INSERT, /* D */
+ F_INSERT, /* E */
+ F_INSERT, /* F */
+ F_INSERT, /* G */
+ F_INSERT, /* H */
+ F_INSERT, /* I */
+ F_INSERT, /* J */
+ F_INSERT, /* K */
+ F_INSERT, /* L */
+ F_INSERT, /* M */
+ F_INSERT, /* N */
+ F_INSERT, /* O */
+ F_INSERT, /* P */
+ F_INSERT, /* Q */
+ F_INSERT, /* R */
+ F_INSERT, /* S */
+ F_INSERT, /* T */
+ F_INSERT, /* U */
+ F_INSERT, /* V */
+ F_INSERT, /* W */
+ F_INSERT, /* X */
+ F_INSERT, /* Y */
+ F_INSERT, /* Z */
+ F_INSERT, /* [ */
+ F_INSERT, /* \ */
+ F_INSERT, /* ] */
+ F_INSERT, /* ^ */
+ F_INSERT, /* _ */
+ F_INSERT, /* ` */
+ F_INSERT, /* a */
+ F_INSERT, /* b */
+ F_INSERT, /* c */
+ F_INSERT, /* d */
+ F_INSERT, /* e */
+ F_INSERT, /* f */
+ F_INSERT, /* g */
+ F_INSERT, /* h */
+ F_INSERT, /* i */
+ F_INSERT, /* j */
+ F_INSERT, /* k */
+ F_INSERT, /* l */
+ F_INSERT, /* m */
+ F_INSERT, /* n */
+ F_INSERT, /* o */
+ F_INSERT, /* p */
+ F_INSERT, /* q */
+ F_INSERT, /* r */
+ F_INSERT, /* s */
+ F_INSERT, /* t */
+ F_INSERT, /* u */
+ F_INSERT, /* v */
+ F_INSERT, /* w */
+ F_INSERT, /* x */
+ F_INSERT, /* y */
+ F_INSERT, /* z */
+ F_INSERT, /* { */
+ F_INSERT, /* | */
+ F_INSERT, /* } */
+ F_INSERT, /* ~ */
+ F_DELPREV, /* ^? */
+ F_UNASSIGNED, /* M-^@ */
+ F_UNASSIGNED, /* M-^A */
+ F_UNASSIGNED, /* M-^B */
+ F_UNASSIGNED, /* M-^C */
+ F_UNASSIGNED, /* M-^D */
+ F_UNASSIGNED, /* M-^E */
+ F_UNASSIGNED, /* M-^F */
+ F_UNASSIGNED, /* M-^G */
+ F_UNASSIGNED, /* M-^H */
+ F_UNASSIGNED, /* M-^I */
+ F_UNASSIGNED, /* M-^J */
+ F_UNASSIGNED, /* M-^K */
+ F_UNASSIGNED, /* M-^L */
+ F_UNASSIGNED, /* M-^M */
+ F_UNASSIGNED, /* M-^N */
+ F_UNASSIGNED, /* M-^O */
+ F_UNASSIGNED, /* M-^P */
+ F_UNASSIGNED, /* M-^Q */
+ F_UNASSIGNED, /* M-^R */
+ F_UNASSIGNED, /* M-^S */
+ F_UNASSIGNED, /* M-^T */
+ F_UNASSIGNED, /* M-^U */
+ F_UNASSIGNED, /* M-^V */
+ F_UNASSIGNED, /* M-^W */
+ F_UNASSIGNED, /* M-^X */
+ F_UNASSIGNED, /* M-^Y */
+ F_UNASSIGNED, /* M-^Z */
+ F_UNASSIGNED, /* M-^[ */
+ F_UNASSIGNED, /* M-^\ */
+ F_UNASSIGNED, /* M-^] */
+ F_UNASSIGNED, /* M-^^ */
+ F_UNASSIGNED, /* M-^_ */
+ F_UNASSIGNED, /* M-SPACE */
+ F_UNASSIGNED, /* M-! */
+ F_UNASSIGNED, /* M-" */
+ F_UNASSIGNED, /* M-# */
+ F_UNASSIGNED, /* M-$ */
+ F_UNASSIGNED, /* M-% */
+ F_UNASSIGNED, /* M-& */
+ F_UNASSIGNED, /* M-' */
+ F_UNASSIGNED, /* M-( */
+ F_UNASSIGNED, /* M-) */
+ F_UNASSIGNED, /* M-* */
+ F_UNASSIGNED, /* M-+ */
+ F_UNASSIGNED, /* M-, */
+ F_UNASSIGNED, /* M-- */
+ F_UNASSIGNED, /* M-. */
+ F_UNASSIGNED, /* M-/ */
+ F_UNASSIGNED, /* M-0 */
+ F_UNASSIGNED, /* M-1 */
+ F_UNASSIGNED, /* M-2 */
+ F_UNASSIGNED, /* M-3 */
+ F_UNASSIGNED, /* M-4 */
+ F_UNASSIGNED, /* M-5 */
+ F_UNASSIGNED, /* M-6 */
+ F_UNASSIGNED, /* M-7 */
+ F_UNASSIGNED, /* M-8 */
+ F_UNASSIGNED, /* M-9 */
+ F_UNASSIGNED, /* M-: */
+ F_UNASSIGNED, /* M-; */
+ F_UNASSIGNED, /* M-< */
+ F_UNASSIGNED, /* M-= */
+ F_UNASSIGNED, /* M-> */
+ F_UNASSIGNED, /* M-? */
+ F_UNASSIGNED, /* M-@ */
+ F_UNASSIGNED, /* M-A */
+ F_UNASSIGNED, /* M-B */
+ F_UNASSIGNED, /* M-C */
+ F_UNASSIGNED, /* M-D */
+ F_UNASSIGNED, /* M-E */
+ F_UNASSIGNED, /* M-F */
+ F_UNASSIGNED, /* M-G */
+ F_UNASSIGNED, /* M-H */
+ F_UNASSIGNED, /* M-I */
+ F_UNASSIGNED, /* M-J */
+ F_UNASSIGNED, /* M-K */
+ F_UNASSIGNED, /* M-L */
+ F_UNASSIGNED, /* M-M */
+ F_UNASSIGNED, /* M-N */
+ F_UNASSIGNED, /* M-O */
+ F_UNASSIGNED, /* M-P */
+ F_UNASSIGNED, /* M-Q */
+ F_UNASSIGNED, /* M-R */
+ F_UNASSIGNED, /* M-S */
+ F_UNASSIGNED, /* M-T */
+ F_UNASSIGNED, /* M-U */
+ F_UNASSIGNED, /* M-V */
+ F_UNASSIGNED, /* M-W */
+ F_UNASSIGNED, /* M-X */
+ F_UNASSIGNED, /* M-Y */
+ F_UNASSIGNED, /* M-Z */
+ F_UNASSIGNED, /* M-[ */
+ F_UNASSIGNED, /* M-\ */
+ F_UNASSIGNED, /* M-] */
+ F_UNASSIGNED, /* M-^ */
+ F_UNASSIGNED, /* M-_ */
+ F_UNASSIGNED, /* M-` */
+ F_UNASSIGNED, /* M-a */
+ F_UNASSIGNED, /* M-b */
+ F_UNASSIGNED, /* M-c */
+ F_UNASSIGNED, /* M-d */
+ F_UNASSIGNED, /* M-e */
+ F_UNASSIGNED, /* M-f */
+ F_UNASSIGNED, /* M-g */
+ F_UNASSIGNED, /* M-h */
+ F_UNASSIGNED, /* M-i */
+ F_UNASSIGNED, /* M-j */
+ F_UNASSIGNED, /* M-k */
+ F_UNASSIGNED, /* M-l */
+ F_UNASSIGNED, /* M-m */
+ F_UNASSIGNED, /* M-n */
+ F_UNASSIGNED, /* M-o */
+ F_UNASSIGNED, /* M-p */
+ F_UNASSIGNED, /* M-q */
+ F_UNASSIGNED, /* M-r */
+ F_UNASSIGNED, /* M-s */
+ F_UNASSIGNED, /* M-t */
+ F_UNASSIGNED, /* M-u */
+ F_UNASSIGNED, /* M-v */
+ F_UNASSIGNED, /* M-w */
+ F_UNASSIGNED, /* M-x */
+ F_UNASSIGNED, /* M-y */
+ F_UNASSIGNED, /* M-z */
+ F_UNASSIGNED, /* M-{ */
+ F_UNASSIGNED, /* M-| */
+ F_UNASSIGNED, /* M-} */
+ F_UNASSIGNED, /* M-~ */
+ F_UNASSIGNED, /* M-^? */
+ /* Extra keys begin here */
+ F_UNASSIGNED, /* f-1 */
+ F_UNASSIGNED, /* f-2 */
+ F_UNASSIGNED, /* f-3 */
+ F_UNASSIGNED, /* f-4 */
+ F_UNASSIGNED, /* f-5 */
+ F_UNASSIGNED, /* f-6 */
+ F_UNASSIGNED, /* f-7 */
+ F_UNASSIGNED, /* f-8 */
+ F_UNASSIGNED, /* f-9 */
+ F_UNASSIGNED, /* f-10 */
+ F_UNASSIGNED, /* f-11 */
+ F_UNASSIGNED, /* f-12 */
+ F_UNASSIGNED, /* f-13 */
+ F_UNASSIGNED, /* f-14 */
+ F_UNASSIGNED, /* f-15 */
+ F_UNASSIGNED, /* f-16 */
+ F_UNASSIGNED, /* f-17 */
+ F_UNASSIGNED, /* f-18 */
+ F_UNASSIGNED, /* f-19 */
+ F_UNASSIGNED, /* f-20 */
+ F_UNASSIGNED, /* f-21 */
+ F_UNASSIGNED, /* f-22 */
+ F_UNASSIGNED, /* f-23 */
+ F_UNASSIGNED, /* f-24 */
+ F_UNASSIGNED, /* PgUp */
+ F_UNASSIGNED, /* PgDn */
+ F_UNASSIGNED, /* end */
+ F_UNASSIGNED, /* home */
+ F_UNASSIGNED, /* LEFT */
+ F_UNASSIGNED, /* UP */
+ F_UNASSIGNED, /* RIGHT */
+ F_UNASSIGNED, /* DOWN */
+ F_UNASSIGNED, /* INS */
+ F_UNASSIGNED, /* DEL */
+ /* ctrl key mappings */
+ F_UNASSIGNED, /* f-1 */
+ F_UNASSIGNED, /* f-2 */
+ F_UNASSIGNED, /* f-3 */
+ F_UNASSIGNED, /* f-4 */
+ F_UNASSIGNED, /* f-5 */
+ F_UNASSIGNED, /* f-6 */
+ F_UNASSIGNED, /* f-7 */
+ F_UNASSIGNED, /* f-8 */
+ F_UNASSIGNED, /* f-9 */
+ F_UNASSIGNED, /* f-10 */
+ F_UNASSIGNED, /* f-11 */
+ F_UNASSIGNED, /* f-12 */
+ F_UNASSIGNED, /* f-13 */
+ F_UNASSIGNED, /* f-14 */
+ F_UNASSIGNED, /* f-15 */
+ F_UNASSIGNED, /* f-16 */
+ F_UNASSIGNED, /* f-17 */
+ F_UNASSIGNED, /* f-18 */
+ F_UNASSIGNED, /* f-19 */
+ F_UNASSIGNED, /* f-20 */
+ F_UNASSIGNED, /* f-21 */
+ F_UNASSIGNED, /* f-22 */
+ F_UNASSIGNED, /* f-23 */
+ F_UNASSIGNED, /* f-24 */
+ F_UNASSIGNED, /* PgUp */
+ F_UNASSIGNED, /* PgDn */
+ F_UNASSIGNED, /* end */
+ F_UNASSIGNED, /* home */
+ F_UNASSIGNED, /* LEFT */
+ F_UNASSIGNED, /* UP */
+ F_UNASSIGNED, /* RIGHT */
+ F_UNASSIGNED, /* DOWN */
+ F_UNASSIGNED, /* INS */
+ F_UNASSIGNED, /* DEL */
+
+ /* alt key mappings */
+ F_UNASSIGNED, /* f-1 */
+ F_UNASSIGNED, /* f-2 */
+ F_UNASSIGNED, /* f-3 */
+ F_UNASSIGNED, /* f-4 */
+ F_UNASSIGNED, /* f-5 */
+ F_UNASSIGNED, /* f-6 */
+ F_UNASSIGNED, /* f-7 */
+ F_UNASSIGNED, /* f-8 */
+ F_UNASSIGNED, /* f-9 */
+ F_UNASSIGNED, /* f-10 */
+ F_UNASSIGNED, /* f-11 */
+ F_UNASSIGNED, /* f-12 */
+ F_UNASSIGNED, /* f-13 */
+ F_UNASSIGNED, /* f-14 */
+ F_UNASSIGNED, /* f-15 */
+ F_UNASSIGNED, /* f-16 */
+ F_UNASSIGNED, /* f-17 */
+ F_UNASSIGNED, /* f-18 */
+ F_UNASSIGNED, /* f-19 */
+ F_UNASSIGNED, /* f-20 */
+ F_UNASSIGNED, /* f-21 */
+ F_UNASSIGNED, /* f-22 */
+ F_UNASSIGNED, /* f-23 */
+ F_UNASSIGNED, /* f-24 */
+ F_UNASSIGNED, /* PgUp */
+ F_UNASSIGNED, /* PgDn */
+ F_UNASSIGNED, /* end */
+ F_UNASSIGNED, /* home */
+ F_UNASSIGNED, /* LEFT */
+ F_UNASSIGNED, /* UP */
+ F_UNASSIGNED, /* RIGHT */
+ F_UNASSIGNED, /* DOWN */
+ F_UNASSIGNED, /* INS */
+ F_UNASSIGNED, /* DEL */
+ /* shift key mappings */
+ F_UNASSIGNED, /* f-1 */
+ F_UNASSIGNED, /* f-2 */
+ F_UNASSIGNED, /* f-3 */
+ F_UNASSIGNED, /* f-4 */
+ F_UNASSIGNED, /* f-5 */
+ F_UNASSIGNED, /* f-6 */
+ F_UNASSIGNED, /* f-7 */
+ F_UNASSIGNED, /* f-8 */
+ F_UNASSIGNED, /* f-9 */
+ F_UNASSIGNED, /* f-10 */
+ F_UNASSIGNED, /* f-11 */
+ F_UNASSIGNED, /* f-12 */
+ F_UNASSIGNED, /* f-13 */
+ F_UNASSIGNED, /* f-14 */
+ F_UNASSIGNED, /* f-15 */
+ F_UNASSIGNED, /* f-16 */
+ F_UNASSIGNED, /* f-17 */
+ F_UNASSIGNED, /* f-18 */
+ F_UNASSIGNED, /* f-19 */
+ F_UNASSIGNED, /* f-20 */
+ F_UNASSIGNED, /* f-21 */
+ F_UNASSIGNED, /* f-22 */
+ F_UNASSIGNED, /* f-23 */
+ F_UNASSIGNED, /* f-24 */
+ F_UNASSIGNED, /* PgUp */
+ F_UNASSIGNED, /* PgDn */
+ F_UNASSIGNED, /* end */
+ F_UNASSIGNED, /* home */
+ F_UNASSIGNED, /* LEFT */
+ F_UNASSIGNED, /* UP */
+ F_UNASSIGNED, /* RIGHT */
+ F_UNASSIGNED, /* DOWN */
+ F_UNASSIGNED, /* INS */
+ F_UNASSIGNED /* DEL */
+};
+
+KEYCMD CcViCmdMap[] = {
+ F_UNASSIGNED, /* ^@ */
+ F_TOBEG, /* ^A */
+ F_UNASSIGNED, /* ^B */
+ F_TTY_INT, /* ^C */
+ F_LIST_CHOICES, /* ^D */
+ F_TOEND, /* ^E */
+ F_UNASSIGNED, /* ^F */
+ F_LIST_GLOB, /* ^G */
+ F_CHARBACK, /* ^H */
+ V_CM_COMPLETE, /* ^I */
+ F_NEWLINE, /* ^J */
+ F_KILLEND, /* ^K */
+ F_CLEARDISP, /* ^L */
+ F_NEWLINE, /* ^M */
+ F_DOWN_HIST, /* ^N */
+ F_TTY_FLUSHO, /* ^O */
+ F_UP_HIST, /* ^P */
+ F_TTY_STARTO, /* ^Q */
+ F_REDISP, /* ^R */
+ F_TTY_STOPO, /* ^S */
+ F_UNASSIGNED, /* ^T */
+ F_KILLBEG, /* ^U */
+ F_UNASSIGNED, /* ^V */
+ F_DELWORDPREV, /* ^W */
+ F_EXPAND, /* ^X */
+ F_UNASSIGNED, /* ^Y */
+ F_UNASSIGNED, /* ^Z */
+ F_METANEXT, /* ^[ */
+ F_TTY_QUIT, /* ^\ */
+ F_UNASSIGNED, /* ^] */
+ F_UNASSIGNED, /* ^^ */
+ F_UNASSIGNED, /* ^_ */
+ F_CHARFWD, /* SPACE */
+ F_EXPAND_HISTORY, /* ! */
+ F_UNASSIGNED, /* " */
+ F_UNASSIGNED, /* # */
+ F_TOEND, /* $ */
+ F_UNASSIGNED, /* % */
+ F_UNASSIGNED, /* & */
+ F_UNASSIGNED, /* ' */
+ F_UNASSIGNED, /* ( */
+ F_UNASSIGNED, /* ) */
+ F_EXPAND_GLOB, /* * */
+ F_DOWN_HIST, /* + */
+ V_RCHAR_BACK, /* , */
+ F_UP_HIST, /* - */
+ F_UNASSIGNED, /* . */
+ V_DSH_META, /* / */
+ V_ZERO, /* 0 */
+ F_ARGDIGIT, /* 1 */
+ F_ARGDIGIT, /* 2 */
+ F_ARGDIGIT, /* 3 */
+ F_ARGDIGIT, /* 4 */
+ F_ARGDIGIT, /* 5 */
+ F_ARGDIGIT, /* 6 */
+ F_ARGDIGIT, /* 7 */
+ F_ARGDIGIT, /* 8 */
+ F_ARGDIGIT, /* 9 */
+ F_UNASSIGNED, /* : */
+ V_RCHAR_FWD, /* ; */
+ F_UNASSIGNED, /* < */
+ F_UNASSIGNED, /* = */
+ F_UNASSIGNED, /* > */
+ V_USH_META, /* ? */
+ F_UNASSIGNED, /* @ */
+ V_ADDEND, /* A */
+ V_WORDBACK, /* B */
+ V_CHGTOEND, /* C */
+ F_KILLEND, /* D */
+ V_ENDWORD, /* E */
+ V_CHAR_BACK, /* F */
+ F_UNASSIGNED, /* G */
+ F_UNASSIGNED, /* H */
+ V_INSBEG, /* I */
+ F_DOWN_SEARCH_HIST, /* J */
+ F_UP_SEARCH_HIST, /* K */
+ F_UNASSIGNED, /* L */
+ F_UNASSIGNED, /* M */
+ V_RSRCH_BACK, /* N */
+ F_XKEY, /* O */
+ F_UNASSIGNED, /* P */
+ F_UNASSIGNED, /* Q */
+ V_REPLMODE, /* R */
+ V_SUBSTLINE, /* S */
+ V_CHARTO_BACK, /* T */
+ F_UNASSIGNED, /* U */
+ F_EXPAND_VARS, /* V */
+ V_WORDFWD, /* W */
+ F_DELPREV, /* X */
+ F_UNASSIGNED, /* Y */
+ F_UNASSIGNED, /* Z */
+ F_XKEY, /* [ */
+ F_UNASSIGNED, /* \ */
+ F_UNASSIGNED, /* ] */
+ F_TOBEG, /* ^ */
+ F_UNASSIGNED, /* _ */
+ F_UNASSIGNED, /* ` */
+ V_ADD, /* a */
+ F_WORDBACK, /* b */
+ V_CHGMETA, /* c */
+ V_DELMETA, /* d */
+ V_EWORD, /* e */
+ V_CHAR_FWD, /* f */
+ F_UNASSIGNED, /* g */
+ F_CHARBACK, /* h */
+ V_INSERT, /* i */
+ F_DOWN_HIST, /* j */
+ F_UP_HIST, /* k */
+ F_CHARFWD, /* l */
+ F_UNASSIGNED, /* m */
+ V_RSRCH_FWD, /* n */
+ F_UNASSIGNED, /* o */
+ F_UNASSIGNED, /* p */
+ F_UNASSIGNED, /* q */
+ V_REPLONE, /* r */
+ V_SUBSTCHAR, /* s */
+ V_CHARTO_FWD, /* t */
+ V_UNDO, /* u */
+ F_EXPAND_VARS, /* v */
+ V_WORDBEGNEXT, /* w */
+ F_DELNEXT_EOF, /* x */
+ F_UNASSIGNED, /* y */
+ F_UNASSIGNED, /* z */
+ F_UNASSIGNED, /* { */
+ F_UNASSIGNED, /* | */
+ F_UNASSIGNED, /* } */
+ V_CHGCASE, /* ~ */
+ F_DELPREV, /* ^? */
+ F_UNASSIGNED, /* M-^@ */
+ F_UNASSIGNED, /* M-^A */
+ F_UNASSIGNED, /* M-^B */
+ F_UNASSIGNED, /* M-^C */
+ F_UNASSIGNED, /* M-^D */
+ F_UNASSIGNED, /* M-^E */
+ F_UNASSIGNED, /* M-^F */
+ F_UNASSIGNED, /* M-^G */
+ F_UNASSIGNED, /* M-^H */
+ F_UNASSIGNED, /* M-^I */
+ F_UNASSIGNED, /* M-^J */
+ F_UNASSIGNED, /* M-^K */
+ F_UNASSIGNED, /* M-^L */
+ F_UNASSIGNED, /* M-^M */
+ F_UNASSIGNED, /* M-^N */
+ F_UNASSIGNED, /* M-^O */
+ F_UNASSIGNED, /* M-^P */
+ F_UNASSIGNED, /* M-^Q */
+ F_UNASSIGNED, /* M-^R */
+ F_UNASSIGNED, /* M-^S */
+ F_UNASSIGNED, /* M-^T */
+ F_UNASSIGNED, /* M-^U */
+ F_UNASSIGNED, /* M-^V */
+ F_UNASSIGNED, /* M-^W */
+ F_UNASSIGNED, /* M-^X */
+ F_UNASSIGNED, /* M-^Y */
+ F_UNASSIGNED, /* M-^Z */
+ F_UNASSIGNED, /* M-^[ */
+ F_UNASSIGNED, /* M-^\ */
+ F_UNASSIGNED, /* M-^] */
+ F_UNASSIGNED, /* M-^^ */
+ F_UNASSIGNED, /* M-^_ */
+ F_UNASSIGNED, /* M-SPACE */
+ F_UNASSIGNED, /* M-! */
+ F_UNASSIGNED, /* M-" */
+ F_UNASSIGNED, /* M-# */
+ F_UNASSIGNED, /* M-$ */
+ F_UNASSIGNED, /* M-% */
+ F_UNASSIGNED, /* M-& */
+ F_UNASSIGNED, /* M-' */
+ F_UNASSIGNED, /* M-( */
+ F_UNASSIGNED, /* M-) */
+ F_UNASSIGNED, /* M-* */
+ F_UNASSIGNED, /* M-+ */
+ F_UNASSIGNED, /* M-, */
+ F_UNASSIGNED, /* M-- */
+ F_UNASSIGNED, /* M-. */
+ F_UNASSIGNED, /* M-/ */
+ F_UNASSIGNED, /* M-0 */
+ F_UNASSIGNED, /* M-1 */
+ F_UNASSIGNED, /* M-2 */
+ F_UNASSIGNED, /* M-3 */
+ F_UNASSIGNED, /* M-4 */
+ F_UNASSIGNED, /* M-5 */
+ F_UNASSIGNED, /* M-6 */
+ F_UNASSIGNED, /* M-7 */
+ F_UNASSIGNED, /* M-8 */
+ F_UNASSIGNED, /* M-9 */
+ F_UNASSIGNED, /* M-: */
+ F_UNASSIGNED, /* M-; */
+ F_UNASSIGNED, /* M-< */
+ F_UNASSIGNED, /* M-= */
+ F_UNASSIGNED, /* M-> */
+ F_HELPME, /* M-? */
+ F_UNASSIGNED, /* M-@ */
+ F_UNASSIGNED, /* M-A */
+ F_UNASSIGNED, /* M-B */
+ F_UNASSIGNED, /* M-C */
+ F_UNASSIGNED, /* M-D */
+ F_UNASSIGNED, /* M-E */
+ F_UNASSIGNED, /* M-F */
+ F_UNASSIGNED, /* M-G */
+ F_UNASSIGNED, /* M-H */
+ F_UNASSIGNED, /* M-I */
+ F_UNASSIGNED, /* M-J */
+ F_UNASSIGNED, /* M-K */
+ F_UNASSIGNED, /* M-L */
+ F_UNASSIGNED, /* M-M */
+ F_UNASSIGNED, /* M-N */
+ F_XKEY, /* M-O *//* extended key esc PWP Mar 88 */
+ F_UNASSIGNED, /* M-P */
+ F_UNASSIGNED, /* M-Q */
+ F_UNASSIGNED, /* M-R */
+ F_UNASSIGNED, /* M-S */
+ F_UNASSIGNED, /* M-T */
+ F_UNASSIGNED, /* M-U */
+ F_UNASSIGNED, /* M-V */
+ F_UNASSIGNED, /* M-W */
+ F_UNASSIGNED, /* M-X */
+ F_UNASSIGNED, /* M-Y */
+ F_UNASSIGNED, /* M-Z */
+ F_XKEY, /* M-[ *//* extended key esc -mf Oct 87 */
+ F_UNASSIGNED, /* M-\ */
+ F_UNASSIGNED, /* M-] */
+ F_UNASSIGNED, /* M-^ */
+ F_UNASSIGNED, /* M-_ */
+ F_UNASSIGNED, /* M-` */
+ F_UNASSIGNED, /* M-a */
+ F_UNASSIGNED, /* M-b */
+ F_UNASSIGNED, /* M-c */
+ F_UNASSIGNED, /* M-d */
+ F_UNASSIGNED, /* M-e */
+ F_UNASSIGNED, /* M-f */
+ F_UNASSIGNED, /* M-g */
+ F_UNASSIGNED, /* M-h */
+ F_UNASSIGNED, /* M-i */
+ F_UNASSIGNED, /* M-j */
+ F_UNASSIGNED, /* M-k */
+ F_UNASSIGNED, /* M-l */
+ F_UNASSIGNED, /* M-m */
+ F_UNASSIGNED, /* M-n */
+ F_UNASSIGNED, /* M-o */
+ F_UNASSIGNED, /* M-p */
+ F_UNASSIGNED, /* M-q */
+ F_UNASSIGNED, /* M-r */
+ F_UNASSIGNED, /* M-s */
+ F_UNASSIGNED, /* M-t */
+ F_UNASSIGNED, /* M-u */
+ F_UNASSIGNED, /* M-v */
+ F_UNASSIGNED, /* M-w */
+ F_UNASSIGNED, /* M-x */
+ F_UNASSIGNED, /* M-y */
+ F_UNASSIGNED, /* M-z */
+ F_UNASSIGNED, /* M-{ */
+ F_UNASSIGNED, /* M-| */
+ F_UNASSIGNED, /* M-} */
+ F_UNASSIGNED, /* M-~ */
+ F_UNASSIGNED, /* M-^? */
+ /* extra keys begin here */
+ F_UNASSIGNED, /* f-1 */
+ F_UNASSIGNED, /* f-2 */
+ F_UNASSIGNED, /* f-3 */
+ F_UNASSIGNED, /* f-4 */
+ F_UNASSIGNED, /* f-5 */
+ F_UNASSIGNED, /* f-6 */
+ F_UNASSIGNED, /* f-7 */
+ F_UNASSIGNED, /* f-8 */
+ F_UNASSIGNED, /* f-9 */
+ F_UNASSIGNED, /* f-10 */
+ F_UNASSIGNED, /* f-11 */
+ F_UNASSIGNED, /* f-12 */
+ F_UNASSIGNED, /* f-13 */
+ F_UNASSIGNED, /* f-14 */
+ F_UNASSIGNED, /* f-15 */
+ F_UNASSIGNED, /* f-16 */
+ F_UNASSIGNED, /* f-17 */
+ F_UNASSIGNED, /* f-18 */
+ F_UNASSIGNED, /* f-19 */
+ F_UNASSIGNED, /* f-20 */
+ F_UNASSIGNED, /* f-21 */
+ F_UNASSIGNED, /* f-22 */
+ F_UNASSIGNED, /* f-23 */
+ F_UNASSIGNED, /* f-24 */
+ F_UNASSIGNED, /* PgUp */
+ F_UNASSIGNED, /* PgDn */
+ F_UNASSIGNED, /* end */
+ F_UNASSIGNED, /* home */
+ F_UNASSIGNED, /* LEFT */
+ F_UNASSIGNED, /* UP */
+ F_UNASSIGNED, /* RIGHT */
+ F_UNASSIGNED, /* DOWN */
+ F_UNASSIGNED, /* INS */
+ F_UNASSIGNED, /* DEL */
+
+ /* ctrl key mappings */
+ F_UNASSIGNED, /* f-1 */
+ F_UNASSIGNED, /* f-2 */
+ F_UNASSIGNED, /* f-3 */
+ F_UNASSIGNED, /* f-4 */
+ F_UNASSIGNED, /* f-5 */
+ F_UNASSIGNED, /* f-6 */
+ F_UNASSIGNED, /* f-7 */
+ F_UNASSIGNED, /* f-8 */
+ F_UNASSIGNED, /* f-9 */
+ F_UNASSIGNED, /* f-10 */
+ F_UNASSIGNED, /* f-11 */
+ F_UNASSIGNED, /* f-12 */
+ F_UNASSIGNED, /* f-13 */
+ F_UNASSIGNED, /* f-14 */
+ F_UNASSIGNED, /* f-15 */
+ F_UNASSIGNED, /* f-16 */
+ F_UNASSIGNED, /* f-17 */
+ F_UNASSIGNED, /* f-18 */
+ F_UNASSIGNED, /* f-19 */
+ F_UNASSIGNED, /* f-20 */
+ F_UNASSIGNED, /* f-21 */
+ F_UNASSIGNED, /* f-22 */
+ F_UNASSIGNED, /* f-23 */
+ F_UNASSIGNED, /* f-24 */
+ F_UNASSIGNED, /* PgUp */
+ F_UNASSIGNED, /* PgDn */
+ F_UNASSIGNED, /* end */
+ F_UNASSIGNED, /* home */
+ F_UNASSIGNED, /* LEFT */
+ F_UNASSIGNED, /* UP */
+ F_UNASSIGNED, /* RIGHT */
+ F_UNASSIGNED, /* DOWN */
+ F_UNASSIGNED, /* INS */
+ F_UNASSIGNED, /* DEL */
+
+ /* alt key mappings */
+ F_UNASSIGNED, /* f-1 */
+ F_UNASSIGNED, /* f-2 */
+ F_UNASSIGNED, /* f-3 */
+ F_UNASSIGNED, /* f-4 */
+ F_UNASSIGNED, /* f-5 */
+ F_UNASSIGNED, /* f-6 */
+ F_UNASSIGNED, /* f-7 */
+ F_UNASSIGNED, /* f-8 */
+ F_UNASSIGNED, /* f-9 */
+ F_UNASSIGNED, /* f-10 */
+ F_UNASSIGNED, /* f-11 */
+ F_UNASSIGNED, /* f-12 */
+ F_UNASSIGNED, /* f-13 */
+ F_UNASSIGNED, /* f-14 */
+ F_UNASSIGNED, /* f-15 */
+ F_UNASSIGNED, /* f-16 */
+ F_UNASSIGNED, /* f-17 */
+ F_UNASSIGNED, /* f-18 */
+ F_UNASSIGNED, /* f-19 */
+ F_UNASSIGNED, /* f-20 */
+ F_UNASSIGNED, /* f-21 */
+ F_UNASSIGNED, /* f-22 */
+ F_UNASSIGNED, /* f-23 */
+ F_UNASSIGNED, /* f-24 */
+ F_UNASSIGNED, /* PgUp */
+ F_UNASSIGNED, /* PgDn */
+ F_UNASSIGNED, /* end */
+ F_UNASSIGNED, /* home */
+ F_UNASSIGNED, /* LEFT */
+ F_UNASSIGNED, /* UP */
+ F_UNASSIGNED, /* RIGHT */
+ F_UNASSIGNED, /* DOWN */
+ F_UNASSIGNED, /* INS */
+ F_UNASSIGNED, /* DEL */
+ /* shift key mappings */
+ F_UNASSIGNED, /* f-1 */
+ F_UNASSIGNED, /* f-2 */
+ F_UNASSIGNED, /* f-3 */
+ F_UNASSIGNED, /* f-4 */
+ F_UNASSIGNED, /* f-5 */
+ F_UNASSIGNED, /* f-6 */
+ F_UNASSIGNED, /* f-7 */
+ F_UNASSIGNED, /* f-8 */
+ F_UNASSIGNED, /* f-9 */
+ F_UNASSIGNED, /* f-10 */
+ F_UNASSIGNED, /* f-11 */
+ F_UNASSIGNED, /* f-12 */
+ F_UNASSIGNED, /* f-13 */
+ F_UNASSIGNED, /* f-14 */
+ F_UNASSIGNED, /* f-15 */
+ F_UNASSIGNED, /* f-16 */
+ F_UNASSIGNED, /* f-17 */
+ F_UNASSIGNED, /* f-18 */
+ F_UNASSIGNED, /* f-19 */
+ F_UNASSIGNED, /* f-20 */
+ F_UNASSIGNED, /* f-21 */
+ F_UNASSIGNED, /* f-22 */
+ F_UNASSIGNED, /* f-23 */
+ F_UNASSIGNED, /* f-24 */
+ F_UNASSIGNED, /* PgUp */
+ F_UNASSIGNED, /* PgDn */
+ F_UNASSIGNED, /* end */
+ F_UNASSIGNED, /* home */
+ F_UNASSIGNED, /* LEFT */
+ F_UNASSIGNED, /* UP */
+ F_UNASSIGNED, /* RIGHT */
+ F_UNASSIGNED, /* DOWN */
+ F_UNASSIGNED, /* INS */
+ F_UNASSIGNED /* DEL */
+};
+ static void
+nt_bad_spec(const Char *keystr)
+{
+ xprintf(CGETS(20, 4, "Bad key spec %S\n"), keystr);
+}
+extern int lstricmp(char*,char*);
+Char nt_translate_bindkey(const Char*s) {
+ char *astr = short2str(s);
+ short fkey;
+ char corm; /* 1 for ctrl map, 2 for meta map, 3 for shift map*/
+ Char keycode = 0;
+
+ corm = 0;
+
+ if (astr[0] == 'C')
+ corm= 1;
+ else if (astr[0] == 'M')
+ corm = 2;
+ else if (astr[0] == 'S') /*shift keymap by avner.lottem@intel.com*/
+ corm = 3;
+
+ if (corm)
+ astr += 2; /* skip C- or M- or S-*/
+
+ fkey = (short)atoi(astr);
+ if (fkey !=0) {
+ keycode = (NT_SPECIFIC_BINDING_OFFSET+ (fkey-1) );
+ }
+ else {
+ if (!_stricmp("pgup",astr)) {
+ keycode = (NT_SPECIFIC_BINDING_OFFSET + KEYPAD_MAPPING_BEGIN);
+ }
+ else if (!_stricmp("pgdown",astr)) {
+ keycode = (NT_SPECIFIC_BINDING_OFFSET + KEYPAD_MAPPING_BEGIN + 1);
+ }
+ else if (!_stricmp("end",astr)) {
+ keycode = (NT_SPECIFIC_BINDING_OFFSET + KEYPAD_MAPPING_BEGIN + 2);
+ }
+ else if (!_stricmp("home",astr)) {
+ keycode = (NT_SPECIFIC_BINDING_OFFSET + KEYPAD_MAPPING_BEGIN + 3);
+ }
+ else if (!_stricmp("left",astr)) {
+ keycode = (NT_SPECIFIC_BINDING_OFFSET + KEYPAD_MAPPING_BEGIN + 4);
+ }
+ else if (!_stricmp("up",astr)) {
+ keycode = (NT_SPECIFIC_BINDING_OFFSET + KEYPAD_MAPPING_BEGIN + 5);
+ }
+ else if (!_stricmp("right",astr)) {
+ keycode = (NT_SPECIFIC_BINDING_OFFSET + KEYPAD_MAPPING_BEGIN + 6);
+ }
+ else if (!_stricmp("down",astr)) {
+ keycode = (NT_SPECIFIC_BINDING_OFFSET + KEYPAD_MAPPING_BEGIN + 7);
+ }
+ else if (!_stricmp("ins",astr)) {
+ keycode = (NT_SPECIFIC_BINDING_OFFSET + INS_DEL_MAPPING_BEGIN );
+ }
+ else if (!_stricmp("del",astr)) {
+ keycode = (NT_SPECIFIC_BINDING_OFFSET +INS_DEL_MAPPING_BEGIN +1 );
+ }
+ else
+ nt_bad_spec(s);
+ }
+ if (keycode && corm) {
+ if (corm == 1)
+ keycode += CTRL_KEY_OFFSET;
+ else if (corm == 2)
+ keycode += ALT_KEY_OFFSET;
+ else if (corm == 3)
+ keycode += SHIFT_KEY_OFFSET;
+ }
+
+ return keycode;
+}
diff --git a/win32/nt.char.c b/win32/nt.char.c
new file mode 100644
index 000000000000..f76bfefd9cb9
--- /dev/null
+++ b/win32/nt.char.c
@@ -0,0 +1,127 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/nt.char.c,v 1.10 2008/10/11 12:47:39 christos Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * nt.char.c : Does NLS-like stuff
+ * -amol
+ *
+ */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdlib.h>
+#include "sh.h"
+
+
+static HMODULE hlangdll;
+
+
+extern DWORD gdwPlatform;
+
+
+unsigned char oem_it(unsigned char ch) {
+ unsigned char ch1[2],ch2[2];
+
+ ch1[0] = ch;
+ ch1[1] = 0;
+
+ OemToChar((char*)ch1,(char*)ch2);
+
+ return ch2[0];
+}
+void nls_dll_unload(void) {
+ FreeLibrary(hlangdll);
+ hlangdll=NULL;
+}
+char * nt_cgets(int set, int msgnum, char *def) {
+
+ int rc;
+ int msg;
+ static char oembuf[256];/*FIXBUF*/
+ WCHAR buffer[256];/*FIXBUF*/
+
+
+
+ if (!hlangdll)
+ return def;
+
+ msg = set * 10000 + msgnum;
+
+ if (gdwPlatform == VER_PLATFORM_WIN32_WINDOWS) {
+ rc = LoadString(hlangdll,msg,oembuf,sizeof(oembuf));
+
+ if(!rc)
+ return def;
+ return oembuf;
+ }
+ rc = LoadStringW(hlangdll,msg,buffer,ARRAYSIZE(buffer));
+
+ if(!rc)
+ return def;
+
+ WideCharToMultiByte(CP_OEMCP,
+ 0,
+ buffer,
+ -1,
+ oembuf,//winbuf,
+ 256,
+ NULL,NULL);
+
+ return oembuf;
+}
+#if defined(DSPMBYTE)
+void nt_autoset_dspmbyte(void) {
+ switch (GetConsoleCP()) {
+ case 932: /* Japan */
+ setcopy(CHECK_MBYTEVAR, STRsjis, VAR_READWRITE);
+ update_dspmbyte_vars();
+ break;
+ }
+}
+
+// _mbmap must be copied to the child during fork()
+unsigned short _mbmap[256] = { 0 };
+#endif
+
+#undef free
+void nls_dll_init(void) {
+
+ char *ptr;
+ size_t size = 0;
+
+
+ if (_dupenv_s(&ptr,&size,"TCSHLANG") == 0){
+
+ if (hlangdll)
+ FreeLibrary(hlangdll);
+ hlangdll = LoadLibrary(ptr);
+
+ free(ptr);
+ }
+}
diff --git a/win32/nt.const.c b/win32/nt.const.c
new file mode 100644
index 000000000000..daee2881ee41
--- /dev/null
+++ b/win32/nt.const.c
@@ -0,0 +1,50 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/nt.const.c,v 1.4 2003/02/08 20:03:29 christos Exp $*/
+/*
+ * nt.const.c: NT-specific String constants for tcsh.
+ */
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#define _h_tc_const
+#include "sh.h"
+#ifdef WINNT_NATIVE
+Char STRoldtitle[] = { 'o', 'l', 'd', 't', 'i', 't', 'l', 'e', '\0' };
+Char STRNTlamepathfix[] = { 'N', 'T', 'l', 'a', 'm', 'e', 'p', 'a', 't', 'h',
+ 'f', 'i','x','\0'};
+Char STRtcshlang[] = { 'T', 'C', 'S', 'H', 'L', 'A', 'N', 'G', '\0' };
+Char STRtcshsubsthb[] = { 'T', 'C', 'S', 'H', 'S', 'U', 'B', 'S', 'T',
+ 'H', 'B', '\0' };
+Char STRtcshonlystartexes[] = { 'T', 'C', 'S', 'H', 'O', 'N', 'L', 'Y', 'S',
+ 'T', 'A', 'R', 'T', 'E', 'X', 'E', 'S', '\0' };
+Char STRNTslowexec[] = {'N','T','s','l','o','w','e','x','e','c','\0'};
+
+Char STRNTcaseifypwd[]={'N','T','c','a','s','e','i','f','y','p','w','d','\0'};
+Char STRdotEXE[] = {'.','E','X','E','\0'};
+
+Char STRNTnoquoteprotect[]={'N','T','n','o','q','u','o','t','e','p','r','o','t','e','c','t','\0'};
+#endif /* WINNT_NATIVE */
diff --git a/win32/nt.screen.c b/win32/nt.screen.c
new file mode 100644
index 000000000000..702591506cf5
--- /dev/null
+++ b/win32/nt.screen.c
@@ -0,0 +1,539 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/nt.screen.c,v 1.14 2006/03/14 01:22:57 mitr Exp $*/
+/*
+ * ed.screen.c: Editor/termcap-curses interface
+ */
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include "sh.h"
+
+
+#include "ed.h"
+#include "tc.h"
+#include "ed.defns.h"
+
+
+/* #define DEBUG_LITERAL */
+
+/*
+ * IMPORTANT NOTE: these routines are allowed to look at the current screen
+ * and the current possition assuming that it is correct. If this is not
+ * true, then the update will be WRONG! This is (should be) a valid
+ * assumption...
+ */
+
+
+
+extern int nt_getsize(int*,int*,int*);
+extern int nt_ClearEOL( void) ;
+extern void NT_ClearEOD( void) ;
+extern void NT_ClearScreen(void) ;
+extern void NT_VisibleBell(void);
+extern void NT_WrapHorizontal(void);
+
+static int GetSize(int *lins, int *cols);
+
+int DisplayWindowHSize;
+ void
+terminit(void)
+{
+ return;
+}
+
+
+
+int T_ActualWindowSize;
+
+static void ReBufferDisplay (void);
+
+
+/*ARGSUSED*/
+ void
+TellTC(void)
+{
+
+ xprintf(CGETS(7, 1, "\n\tYou're using a Windows console.\n"));
+}
+
+
+ static void
+ReBufferDisplay(void)
+{
+ register int i;
+ Char **b;
+ Char **bufp;
+ int lins,cols;
+
+ nt_getsize(&lins,&cols,&DisplayWindowHSize);
+
+ b = Display;
+ Display = NULL;
+ if (b != NULL) {
+ for (bufp = b; *bufp != NULL; bufp++)
+ xfree((ptr_t) * bufp);
+ xfree((ptr_t) b);
+ }
+ b = Vdisplay;
+ Vdisplay = NULL;
+ if (b != NULL) {
+ for (bufp = b; *bufp != NULL; bufp++)
+ xfree((ptr_t) * bufp);
+ xfree((ptr_t) b);
+ }
+ TermH = cols;
+
+ TermV = (INBUFSIZE * 4) / TermH + 1;/*FIXBUF*/
+ b = (Char **) xmalloc((size_t) (sizeof(*b) * (TermV + 1)));
+ for (i = 0; i < TermV; i++)
+ b[i] = (Char *) xmalloc((size_t) (sizeof(*b[i]) * (TermH + 1)));
+ b[TermV] = NULL;
+ Display = b;
+ b = (Char **) xmalloc((size_t) (sizeof(*b) * (TermV + 1)));
+ for (i = 0; i < TermV; i++)
+ b[i] = (Char *) xmalloc((size_t) (sizeof(*b[i]) * (TermH + 1)));
+ b[TermV] = NULL;
+ Vdisplay = b;
+}
+
+ void
+SetTC(char *what, char *how)
+{
+ int li,win,co;
+
+ nt_getsize(&li,&co,&win);
+ if (!lstrcmp(what,"li")) {
+ li = atoi(how);
+
+ }else if(!lstrcmp(what,"co")) { //set window, not buffer size
+ win = atoi(how);
+ }
+ else
+ stderror(ERR_SYSTEM, "SetTC","Sorry, this function is not supported");
+
+ ChangeSize(li,win);
+ return;
+}
+
+
+/*
+ * Print the termcap string out with variable substitution
+ */
+ void
+EchoTC(Char **v)
+{
+ Char **globbed;
+ char cv[BUFSIZE];/*FIXBUF*/
+ int verbose = 0, silent = 0;
+ static char *fmts = "%s\n", *fmtd = "%d\n";
+ int li,co;
+
+
+ setname("echotc");
+
+ v = glob_all_or_error(v);
+ globbed = v;
+ cleanup_push(globbed, blk_cleanup);
+
+ if (!v || !*v || *v[0] == '\0')
+ goto end;
+ if (v[0][0] == '-') {
+ switch (v[0][1]) {
+ case 'v':
+ verbose = 1;
+ break;
+ case 's':
+ silent = 1;
+ break;
+ default:
+ stderror(ERR_NAME | ERR_TCUSAGE);
+ break;
+ }
+ v++;
+ }
+ if (!*v || *v[0] == '\0')
+ goto end;
+ (void) StringCbCopy(cv,sizeof(cv), short2str(*v));
+
+ GetSize(&li,&co);
+
+ if(!lstrcmp(cv,"rows") || !lstrcmp(cv,"lines") ) {
+ xprintf(fmtd,T_Lines);
+ goto end;
+ }
+ else if(!lstrcmp(cv,"cols") ) {
+ xprintf(fmtd,T_ActualWindowSize);
+ goto end;
+ }
+ else if(!lstrcmp(cv,"buffer") ) {
+ xprintf(fmtd,T_Cols);
+ goto end;
+ }
+ else
+ stderror(ERR_SYSTEM, "EchoTC","Sorry, this function is not supported");
+
+end:
+ cleanup_until(globbed);
+}
+
+int GotTermCaps = 0;
+
+
+ void
+ResetArrowKeys(void)
+{
+}
+
+ void
+DefaultArrowKeys(void)
+{
+}
+
+
+ int
+SetArrowKeys(const CStr *name, XmapVal *fun, int type)
+{
+ UNREFERENCED_PARAMETER(name);
+ UNREFERENCED_PARAMETER(fun);
+ UNREFERENCED_PARAMETER(type);
+ return -1;
+}
+
+ int
+IsArrowKey(Char *name)
+{
+ UNREFERENCED_PARAMETER(name);
+ return 0;
+}
+
+ int
+ClearArrowKeys(const CStr *name)
+{
+ UNREFERENCED_PARAMETER(name);
+ return -1;
+}
+
+ void
+PrintArrowKeys(const CStr *name)
+{
+ UNREFERENCED_PARAMETER(name);
+ return;
+}
+
+
+ void
+BindArrowKeys(void)
+{
+ return;
+}
+
+#define GoodStr(ignore) 1
+ void
+SetAttributes(Char atr)
+{
+ atr &= ATTRIBUTES;
+}
+
+/* PWP 6-27-88 -- if the tty driver thinks that we can tab, we ask termcap */
+ int
+CanWeTab(void)
+{
+ return 1;
+}
+
+/* move to line <where> (first line == 0) as efficiently as possible; */
+ void
+MoveToLine(int where)
+{
+ int del;
+
+ if (where == CursorV)
+ return;
+
+ if (where > TermV) {
+#ifdef DEBUG_SCREEN
+ xprintf("MoveToLine: where is ridiculous: %d\r\n", where);
+ flush();
+#endif /* DEBUG_SCREEN */
+ return;
+ }
+
+ del = where - CursorV;
+
+ NT_MoveToLineOrChar(del, 1);
+
+ CursorV = where; /* now where is here */
+}
+
+/* move to character position (where) as efficiently as possible */
+ void
+MoveToChar(int where)
+{
+ if (where == CursorH)
+ return;
+
+ if (where >= TermH) {
+#ifdef DEBUG_SCREEN
+ xprintf("MoveToChar: where is riduculous: %d\r\n", where);
+ flush();
+#endif /* DEBUG_SCREEN */
+ return;
+ }
+
+ if (!where) { /* if where is first column */
+ //(void) putraw('\r'); /* do a CR */
+ NT_MoveToLineOrChar(where, 0);
+ flush();
+ CursorH = 0;
+ return;
+ }
+
+ NT_MoveToLineOrChar(where, 0);
+ CursorH = where; /* now where is here */
+}
+
+ void
+so_write(register Char *cp, register int n)
+{
+ if (n <= 0)
+ return; /* catch bugs */
+
+ if (n > TermH) {
+ return;
+ }
+
+ do {
+ if (*cp & LITERAL) {
+ Char *d;
+
+ for (d = litptr + (*cp++ & ~LITERAL) * LIT_FACTOR; *d;
+ d++)
+ (void) putraw(*d);
+ }
+ else
+ (void) putraw(*cp++);
+ CursorH++;
+ } while (--n);
+
+ if (CursorH >= TermH) { /* wrap? */
+ CursorH = 0;
+ CursorV++;
+ NT_WrapHorizontal();
+
+ }
+ else if(CursorH >= DisplayWindowHSize) {
+ flush();
+ NT_MoveToLineOrChar(CursorH,0);
+ }
+}
+
+
+ void
+DeleteChars(int num) /* deletes <num> characters */
+{
+ if (num <= 0)
+ return;
+
+ if (!T_CanDel) {
+#ifdef DEBUG_EDIT
+ xprintf(CGETS(7, 16, "ERROR: cannot delete\r\n"));
+#endif /* DEBUG_EDIT */
+ flush();
+ return;
+ }
+
+ if (num > TermH) {
+#ifdef DEBUG_SCREEN
+ xprintf(CGETS(7, 17, "DeletChars: num is riduculous: %d\r\n"), num);
+ flush();
+#endif /* DEBUG_SCREEN */
+ return;
+ }
+
+}
+
+/* Puts terminal in insert character mode, or inserts num characters in the
+ line */
+ void
+Insert_write(register Char *cp, register int num)
+{
+ UNREFERENCED_PARAMETER(cp);
+
+ if (num <= 0)
+ return;
+ if (!T_CanIns) {
+#ifdef DEBUG_EDIT
+ xprintf(CGETS(7, 18, "ERROR: cannot insert\r\n"));
+#endif /* DEBUG_EDIT */
+ flush();
+ return;
+ }
+
+ if (num > TermH) {
+#ifdef DEBUG_SCREEN
+ xprintf(CGETS(7, 19, "StartInsert: num is riduculous: %d\r\n"), num);
+ flush();
+#endif /* DEBUG_SCREEN */
+ return;
+ }
+
+
+}
+
+/* clear to end of line. There are num characters to clear */
+ void
+ClearEOL(int num)
+{
+
+ if (num <= 0)
+ return;
+
+ nt_ClearEOL();
+
+}
+
+ void
+ClearScreen(void)
+{ /* clear the whole screen and home */
+
+ NT_ClearScreen();
+
+}
+
+ void
+SoundBeep(void)
+{ /* produce a sound */
+ beep_cmd ();
+ if (adrof(STRnobeep))
+ return;
+
+ if (adrof(STRvisiblebell))
+ NT_VisibleBell(); /* visible bell */
+ else
+ MessageBeep(MB_ICONQUESTION);
+}
+
+ void
+ClearToBottom(void)
+{ /* clear to the bottom of the screen */
+ NT_ClearEOD();
+
+}
+
+ void
+GetTermCaps(void)
+{
+ int lins,cols;
+
+ nt_getsize(&lins,&cols,&DisplayWindowHSize);
+
+ GotTermCaps = 1;
+
+ T_Cols = cols;
+ T_Lines = lins;
+ T_ActualWindowSize = DisplayWindowHSize;
+ T_Margin = MARGIN_AUTO;
+ T_CanCEOL = 1;
+ T_CanDel = 0;
+ T_CanIns = 0;
+ T_CanUP = 1;
+
+ ReBufferDisplay();
+ ClearDisp();
+
+ return;
+}
+/* GetSize():
+ * Return the new window size in lines and cols, and
+ * true if the size was changed.
+ */
+ int
+GetSize(int *lins, int *cols)
+{
+
+ int ret = 0;
+
+ *lins = T_Lines;
+
+ *cols = T_Cols;
+
+ nt_getsize(lins,cols,&DisplayWindowHSize);
+
+ // compare the actual visible window size,but return the console buffer size
+ // this is seriously demented.
+ ret = (T_Lines != *lins || T_ActualWindowSize != DisplayWindowHSize);
+
+ T_Lines = *lins;
+ T_Cols = *cols;
+ T_ActualWindowSize = DisplayWindowHSize;
+
+ return ret;
+}
+ void
+ChangeSize(int lins, int cols)
+{
+
+ int rc = 0;
+ // here we're setting the window size, not the buffer size.
+ //
+ nt_set_size(lins,cols);
+
+ rc = GetSize(&lins,&cols);
+
+
+ ReBufferDisplay(); /* re-make display buffers */
+ ClearDisp();
+}
+ void
+PutPlusOne(Char c, int width)
+{
+ extern int OldvcV;
+
+ while (width > 1 && CursorH + width > DisplayWindowHSize)
+ PutPlusOne(' ', 1);
+ if ((c & LITERAL) != 0) {
+ Char *d;
+ for (d = litptr + (c & ~LITERAL) * LIT_FACTOR; *d; d++)
+ (void) putwraw(*d);
+ } else {
+ (void) putwraw(c);
+ }
+
+ Display[CursorV][CursorH++] = (Char) c;
+ while (--width > 0)
+ Display[CursorV][CursorH++] = CHAR_DBWIDTH;
+
+ if (CursorH >= TermH) { /* if we must overflow */
+ CursorH = 0;
+ CursorV++;
+ OldvcV++;
+ NT_WrapHorizontal();
+ }
+ else if(CursorH >= DisplayWindowHSize) {
+ NT_MoveToLineOrChar(CursorH,0);
+ }
+}
diff --git a/win32/nt.who.c b/win32/nt.who.c
new file mode 100644
index 000000000000..59ef39eec42d
--- /dev/null
+++ b/win32/nt.who.c
@@ -0,0 +1,275 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/nt.who.c,v 1.6 2006/03/05 08:59:36 amold Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * nt.who.c: Support for who-like functions, using NETBIOS
+ * -amol
+ *
+ */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <nb30.h>
+#include <stdio.h>
+#include "sh.h"
+
+
+typedef struct _ASTAT_ {
+ ADAPTER_STATUS adapt;
+ NAME_BUFFER NameBuff [10];
+} ASTAT;
+
+typedef struct _n_ctx {
+ NCB ncb;
+ u_char usr_name[NCBNAMSZ];
+ u_char mach_name[NCBNAMSZ];
+} ncb_ctx;
+
+typedef UCHAR (APIENTRY *netbios_func)(NCB *);
+
+
+static netbios_func p_Netbios =0;
+static int ginited = 0;
+
+static CRITICAL_SECTION nb_critter;
+static HMODULE hnetapi;
+
+
+extern int add_to_who_list(u_char *,u_char*);
+
+void init_netbios(void ) {
+
+
+ if (!ginited) {
+ hnetapi = LoadLibrary("NETAPI32.DLL");
+ if (!hnetapi)
+ return ;
+
+ p_Netbios = (netbios_func)GetProcAddress(hnetapi,"Netbios");
+
+ if (!p_Netbios )
+ return ;
+ ginited = 1;
+ }
+ InitializeCriticalSection(&nb_critter);
+}
+void cleanup_netbios(void) {
+ if (hnetapi){
+ DeleteCriticalSection(&nb_critter);
+ FreeLibrary(hnetapi);
+ }
+}
+void CALLBACK complete_ncb( NCB * p_ncb) {
+
+ int count,i;
+ ADAPTER_STATUS *p_ad;
+ ASTAT *pas;
+ char *p1;
+ ncb_ctx *ctx = (ncb_ctx *)p_ncb;
+
+ if (p_ncb->ncb_retcode)
+ goto end;
+
+ __try {
+
+ EnterCriticalSection(&nb_critter);
+ pas = ((ASTAT*) p_ncb->ncb_buffer);
+ p_ad = &pas->adapt;
+
+ count = p_ad->name_count;
+
+ if (count <=0 )
+ __leave;
+
+ if (ctx->usr_name[0] == 0) { //any user on given machine
+ for(i=0; i<count;i++) {
+ if (pas->NameBuff[i].name[15] == 03) { // unique name
+ if (!strncmp((char*)(pas->NameBuff[i].name),
+ (char*)(p_ncb->ncb_callname),
+ NCBNAMSZ)) {
+ continue;
+ }
+ else {
+ p1 = strchr((char*)(pas->NameBuff[i].name),' ');
+ if (p1)
+ *p1 = 0;
+ else
+ pas->NameBuff[i].name[15]= 0;
+ add_to_who_list(pas->NameBuff[i].name,
+ ctx->mach_name);
+ break;
+ }
+ }
+ }
+ }
+ else if (ctx->mach_name[0] == 0) { // given user on any machine
+ for(i=0; i<count;i++) {
+ if (pas->NameBuff[i].name[15] == 03) { // unique name
+ if (!strncmp((char*)(pas->NameBuff[i].name),
+ (char*)(p_ncb->ncb_callname),
+ NCBNAMSZ))
+ continue;
+ else {
+ p1 = strchr((char*)(pas->NameBuff[i].name),' ');
+ if (p1)
+ *p1 = 0;
+ else
+ pas->NameBuff[i].name[15]= 0;
+
+ add_to_who_list(ctx->usr_name, pas->NameBuff[i].name);
+
+ break;
+ }
+ }
+ }
+ }
+ else { // specific user on specific machine
+ for(i=0; i<count;i++) {
+ if (pas->NameBuff[i].name[15] == 03) { // unique name
+ // skip computer name
+ if (!strncmp((char*)(pas->NameBuff[i].name),
+ (char*)(p_ncb->ncb_callname),
+ NCBNAMSZ)) {
+ continue;
+ }
+ else if (!strncmp((char*)(pas->NameBuff[i].name),
+ (char*)(ctx->usr_name),
+ lstrlen((char*)ctx->usr_name))) {
+ p1 = strchr((char*)pas->NameBuff[i].name,' ');
+ if (p1)
+ *p1 = 0;
+ else
+ pas->NameBuff[i].name[15]= 0;
+ add_to_who_list(pas->NameBuff[i].name,ctx->mach_name);
+ break;
+ }
+ }
+ }
+ }
+ }
+ __except(GetExceptionCode()) {
+ ;
+ }
+ LeaveCriticalSection(&nb_critter);
+end:
+ heap_free(p_ncb->ncb_buffer);
+ heap_free(p_ncb);
+ return;
+}
+void start_ncbs (Char **vp) {
+
+ ncb_ctx * p_ctx;
+ NCB *Ncb;
+ Char **namevec = vp;
+ char *p1,*p2,*nb_name;
+ UCHAR uRetCode;
+ ASTAT *Adapter;
+
+ if (!ginited) {
+ init_netbios();
+ }
+ if (!ginited)
+ return;
+
+ for (namevec = vp;*namevec != NULL;namevec +=2) {
+
+ p_ctx = heap_alloc(sizeof(ncb_ctx));
+ Adapter = heap_alloc(sizeof(ASTAT));
+
+ Ncb = (NCB*)p_ctx;
+
+ memset( Ncb, 0, sizeof(NCB) );
+
+ Ncb->ncb_command = NCBRESET;
+ Ncb->ncb_lana_num = 0;
+
+ uRetCode = p_Netbios( Ncb );
+
+ if(uRetCode)
+ goto cleanup;
+
+ if ((**namevec == '\0' ) || ( *(namevec +1) == NULL) ||
+ (**(namevec +1) == '\0') )
+ break;
+
+
+ p1 = short2str(*namevec);
+ if (!_stricmp(p1,"any") ) {
+ p_ctx->usr_name[0] = 0;
+ }
+ else {
+ StringCbCopy((char*)p_ctx->usr_name,sizeof(p_ctx->usr_name),p1);
+ }
+ p1 = (char*)&(p_ctx->usr_name[0]);
+
+ p2 = short2str(*(namevec+1));
+ //
+ // If machine is not "any", make it the callname
+ //
+ if (!_stricmp(p2,"any") ) {
+ p_ctx->mach_name[0] = 0;
+ nb_name = p1;
+ }
+ else {
+ StringCbCopy((char*)p_ctx->mach_name,sizeof(p_ctx->mach_name),p2);
+ nb_name = p2;
+ }
+
+ // do not permit any any
+ //
+ if( (p_ctx->mach_name[0] == 0) && (p_ctx->usr_name[0] == 0) )
+ goto cleanup;
+
+
+
+ memset( Ncb, 0, sizeof (NCB) );
+
+ Ncb->ncb_command = NCBASTAT | ASYNCH;
+ Ncb->ncb_lana_num = 0;
+
+ memset(Ncb->ncb_callname,' ',sizeof(Ncb->ncb_callname));
+
+ Ncb->ncb_callname[15]=03;
+
+ memcpy(Ncb->ncb_callname,nb_name,lstrlen(nb_name));
+
+ Ncb->ncb_buffer = (u_char *) Adapter;
+ Ncb->ncb_length = sizeof(*Adapter);
+
+ Ncb->ncb_post = complete_ncb;
+
+ uRetCode = p_Netbios( Ncb );
+ }
+ return;
+
+cleanup:
+ heap_free(Adapter);
+ heap_free(p_ctx);
+ return;
+}
diff --git a/win32/ntb1.c b/win32/ntb1.c
new file mode 100644
index 000000000000..ccc54451c116
--- /dev/null
+++ b/win32/ntb1.c
@@ -0,0 +1,35 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/ntb1.c,v 1.4 2004/05/19 18:22:28 christos Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+//
+// Placeholder variable to mark beginning of data segment.
+// -amol
+//
+#include "ntport.h"
+unsigned long bookend1=0;
diff --git a/win32/ntb2.c b/win32/ntb2.c
new file mode 100644
index 000000000000..99a119917185
--- /dev/null
+++ b/win32/ntb2.c
@@ -0,0 +1,34 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/ntb2.c,v 1.4 2004/05/19 18:22:28 christos Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+//
+// Placeholder variable to mark end of data segment.
+//
+#include "ntport.h"
+unsigned long bookend2=0;
diff --git a/win32/ntfunc.c b/win32/ntfunc.c
new file mode 100644
index 000000000000..2799715cb109
--- /dev/null
+++ b/win32/ntfunc.c
@@ -0,0 +1,1207 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/ntfunc.c,v 1.19 2006/08/27 01:13:28 amold Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * ntfunc.c builtins specific to NT
+ * -amol
+ *
+ */
+#pragma warning(push,3)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <shellapi.h>
+#pragma warning(pop)
+#include <errno.h>
+#include <sh.h>
+#include "ed.h"
+
+#include "nt.const.h"
+
+
+extern DWORD gdwPlatform;
+
+extern int StrQcmp(Char *, Char *);
+extern int hashval_extern(Char*);
+extern int bit_extern(int,int);
+extern void bis_extern(int,int);
+extern int hashname(Char*);
+
+extern void NT_ClearScreen_WholeBuffer(void);
+
+BOOL is_url(const char *cmd);
+
+void error(char * ) ;
+void make_err_str(unsigned int ,char *,int) ;
+
+#define INF INT_MAX
+struct biltins nt_bfunc[] = {
+ { "cls", docls, 0, 0 },
+#ifdef NTDBG
+ { "debugbreak", dodebugbreak, 0, 0 },
+#endif /* NTDBG */
+ { "ps", dops, 0, 1 },
+ { "shutdown", doshutdown, 0, 2 },
+ { "start", dostart, 1, INF },
+ { "title", dotitle, 1, INF },
+};
+int nt_nbfunc = sizeof nt_bfunc / sizeof *nt_bfunc;
+
+char start_usage[] = { ":\n \
+ Similar to cmd.exe's start \n \
+ start [-Ttitle] [-Dpath] [-min] [-max] [-separate] [-shared] \n \
+ [-low|normal|realtime|high] program args \n \
+ Batch/Cmd files must be started with CMD /K \n"
+};
+
+struct biltins * nt_check_additional_builtins(Char *cp) {
+
+ register struct biltins *bp1, *bp2;
+ int i;
+
+ for (bp1 = nt_bfunc, bp2 = nt_bfunc + nt_nbfunc; bp1 < bp2;bp1++) {
+
+ if ((i = ((char) *cp) - *bp1->bname) == 0 &&
+ (i = StrQcmp(cp, str2short(bp1->bname))) == 0)
+ return bp1;
+ }
+ return (0);
+}
+void nt_print_builtins(size_t maxwidth) {
+
+ /* would use print_by_column() in tw.parse.c but that assumes
+ * we have an array of Char * to pass.. (sg)
+ */
+ extern int Tty_raw_mode;
+ extern int TermH; /* from the editor routines */
+ extern int lbuffed; /* from sh.print.c */
+
+ register struct biltins *b;
+ register size_t row, col, columns, rows;
+ size_t w ,oldmax;
+
+
+ /* find widest string */
+
+ oldmax = maxwidth;
+
+ for ( b = nt_bfunc; b < &nt_bfunc[nt_nbfunc]; ++b)
+ maxwidth = max(maxwidth, (int)lstrlen(b->bname));
+
+ if (oldmax != maxwidth)
+ ++maxwidth; /* for space */
+
+ columns = (TermH + 1) / maxwidth; /* PWP: terminal size change */
+ if (!columns)
+ columns = 1;
+ rows = (nt_nbfunc + (columns - 1)) / columns;
+
+ for (b = nt_bfunc, row = 0; row < rows; row++) {
+ for (col = 0; col < columns; col++) {
+ if (b < &nt_bfunc[nt_nbfunc]) {
+ w = (int)lstrlen(b->bname);
+ xprintf("%s", b->bname);
+ if (col < (columns - 1)) /* Not last column? */
+ for (; w < maxwidth; w++)
+ xputchar(' ');
+ ++b;
+ }
+ }
+ if (Tty_raw_mode)
+ xputchar('\r');
+ xputchar('\n');
+ }
+
+}
+/* patch from TAGA Nayuta for start . */
+BOOL is_directory(const char *the_cmd) {
+ DWORD attr = GetFileAttributes(the_cmd);
+ return (attr != 0xFFFFFFFF &&
+ (attr & FILE_ATTRIBUTE_DIRECTORY));
+}
+void dostart(Char ** vc, struct command *c) {
+
+ char *cmdstr,*cmdend,*ptr;
+ char argv0[256];/*FIXBUF*/
+ DWORD cmdsize;
+ char *currdir=NULL;
+ char *savepath;
+ char **v = NULL;
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ DWORD dwCreationFlags=CREATE_NEW_CONSOLE;
+ DWORD k,cmdlen,j,jj,ret;
+
+
+ UNREFERENCED_PARAMETER(c);
+ vc++;
+
+ cmdsize = 512;
+ cmdstr = heap_alloc(cmdsize);
+ cmdend = cmdstr;
+ cmdlen = 0;
+
+ memset(&si,0,sizeof(si));
+ si.cb = sizeof(si);
+
+ vc = glob_all_or_error(vc);
+ v = short2blk(vc);
+ if(v == NULL) {
+ stderror(ERR_NOMEM);
+ return;
+ }
+ blkfree(vc);
+ for (k = 0; v[k] != NULL ; k++){
+
+ if ( v[k][0] == '-' ) {
+ /* various options */
+ if( (v[k][1] == 'T') || (v[k][1] == 't'))
+ si.lpTitle =&( v[k][2]);
+ else if ( (v[k][1] == 'D') || (v[k][1] == 'd'))
+ currdir =&( v[k][2]);
+ else if (!_stricmp(&v[k][1],"MIN") )
+ si.wShowWindow = SW_SHOWMINIMIZED;
+ else if (!_stricmp(&v[k][1],"MAX") )
+ si.wShowWindow = SW_SHOWMAXIMIZED;
+ else if (!_stricmp(&v[k][1],"SEPARATE") )
+ dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
+ else if (!_stricmp(&v[k][1],"SHARED") )
+ dwCreationFlags |= CREATE_SHARED_WOW_VDM;
+ else if (!_stricmp(&v[k][1],"LOW") )
+ dwCreationFlags |= IDLE_PRIORITY_CLASS;
+ else if (!_stricmp(&v[k][1],"NORMAL") )
+ dwCreationFlags |= NORMAL_PRIORITY_CLASS;
+ else if (!_stricmp(&v[k][1],"HIGH") )
+ dwCreationFlags |= HIGH_PRIORITY_CLASS;
+ else if (!_stricmp(&v[k][1],"REALTIME") )
+ dwCreationFlags |= REALTIME_PRIORITY_CLASS;
+ else{
+ blkfree((Char **)v);
+ stderror(ERR_SYSTEM,start_usage,"See CMD.EXE for more info");/*FIXRESET*/
+ }
+ }
+ else{ // non-option arg
+ break;
+ }
+ }
+ /*
+ * Stop the insanity of requiring start "tcsh -l"
+ * Option processing now stops at first non-option arg
+ * -amol 5/30/96
+ */
+ for (jj=k;v[jj] != NULL; jj++) {
+ j=(lstrlen(v[jj]) + 2);
+ if (j + cmdlen > cmdsize) {
+ ptr = cmdstr;
+ cmdstr = heap_realloc(cmdstr, max(cmdsize << 1, j+cmdlen) );
+ if(!cmdstr)
+ {
+ heap_free(ptr);
+ stderror(ERR_NOMEM,"start");/*FIXRESET*/
+ }
+ cmdend = cmdstr + (cmdend - ptr);
+ cmdsize <<= 1;
+ }
+ ptr = v[jj];
+ while (*ptr) {
+ *cmdend++ = *ptr++;
+ cmdlen++;
+ }
+ *cmdend++ = ' ';
+ cmdlen++;
+ }
+ if (jj == k) {
+ blkfree((Char **)v);
+ stderror(ERR_SYSTEM,start_usage,"See CMD.EXE for more info");/*FIXRESET*/
+ return;
+ }
+ *cmdend = 0;
+ StringCbCopy(argv0,sizeof(argv0),v[k]);
+
+
+ /*
+ * strictly speaking, it should do no harm to set the path
+ * back to '\'-delimited even in the parent, but in the
+ * interest of consistency, we save the old value and restore it
+ * later
+ */
+
+ savepath = fix_path_for_child();
+
+ if (! CreateProcess(NULL,
+ cmdstr,
+ NULL,
+ NULL,
+ FALSE,
+ dwCreationFlags,
+ NULL,
+ currdir,
+ &si,
+ &pi) ) {
+
+ restore_path(savepath);
+
+ ret = GetLastError();
+ if (ret == ERROR_BAD_EXE_FORMAT || ret == ERROR_ACCESS_DENIED ||
+ (ret == ERROR_FILE_NOT_FOUND &&
+ (is_url(v[k]) || is_directory(v[k]))
+ )
+ ) {
+
+ char erbuf[MAX_PATH];
+
+ errno = ENOEXEC;
+
+ try_shell_ex(&v[k],0,FALSE);
+
+ heap_free(cmdstr); /* free !! */
+
+ if (errno) {
+ strerror_s(erbuf,sizeof(erbuf),errno);
+ stderror(ERR_ARCH,argv0,erbuf);/*FIXRESET*/
+ }
+ }
+ else if (ret == ERROR_INVALID_PARAMETER) {
+
+ errno = ENAMETOOLONG;
+
+ heap_free(cmdstr); /* free !! */
+
+ stderror(ERR_TOOLARGE,argv0);/*FIXRESET*/
+
+ }
+ else {
+ errno = ENOENT;
+ if (
+ ( (v[k][0] == '\\') ||(v[k][0] == '/') ) &&
+ ( (v[k][1] == '\\') ||(v[k][1] == '/') ) &&
+ (!v[k+1])
+ )
+ try_shell_ex(&v[k],0,FALSE);
+
+ heap_free(cmdstr); /* free !! */
+ if (errno) {
+ stderror(ERR_NOTFOUND,argv0);/*FIXRESET*/
+ }
+ }
+ }
+ else {
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+
+ heap_free(cmdstr);
+ restore_path(savepath);
+ }
+ blkfree((Char **)v);
+ return;
+}
+void error(char * ebuf) {
+
+ write(2,(unsigned char*)ebuf,lstrlen(ebuf));
+}
+void make_err_str(unsigned int error,char *buf,int size) {
+
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ error,
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
+ buf,
+ size,
+ NULL);
+ return;
+
+}
+
+// We should really use the environ array, but NT likes it to be sorted.
+// So we just let the win32 apis take care of inheritance of the environment.
+// -amol 4/7/97
+//
+//char nameBuf[BUFSIZ], valBuf[BUFSIZ];
+char dummy;
+char *nameBuf=&dummy, *valBuf=&dummy;
+
+void nt_set_env(const Char *name, const Char *val) {
+ char *cname, *cval;
+ int len;
+
+ cname = name?short2str(name):NULL;
+ if(cname) {
+ len = lstrlen(cname);
+ nameBuf = heap_alloc(len+1);
+ if (!nameBuf) {
+ stderror(ERR_TOOLARGE);
+ }
+ StringCbCopy(nameBuf,len+1,cname);
+ }
+ cval = val?short2str(val):NULL;
+ if(cval) {
+ len = lstrlen(cval);
+ valBuf = heap_alloc(len+1);
+ StringCbCopy(valBuf,len+1,cval);
+ }
+
+ SetEnvironmentVariable(nameBuf,cval?valBuf:NULL);
+
+ if (!lstrcmp(nameBuf,"TCSHONLYSTARTEXES"))
+ init_shell_dll();
+
+ heap_free(nameBuf);
+ if (cval)
+ heap_free(valBuf);
+
+
+}
+void dotitle(Char **vc, struct command * c) {
+
+ int k;
+ char titlebuf[512];
+ char errbuf[128],err2[128];
+ char **v;
+
+ UNREFERENCED_PARAMETER(c);
+ vc++;
+ vc = glob_all_or_error(vc);
+ cleanup_push(vc, blk_cleanup);
+
+ if ((k=GetConsoleTitle(titlebuf,512) ) != 0) {
+ titlebuf[k]=0;
+ setcopy(STRoldtitle,str2short(titlebuf),VAR_READWRITE);
+ }
+
+ memset(titlebuf,0,512);
+ v = short2blk(vc);
+ cleanup_until(vc);
+ cleanup_push((Char **)v, blk_cleanup);
+ for (k = 0; v[k] != NULL ; k++){
+ __try {
+ StringCbCat(titlebuf,sizeof(titlebuf),v[k]);
+ StringCbCat(titlebuf,sizeof(titlebuf)," ");
+ }
+ __except(GetExceptionCode()) {
+ stderror(ERR_TOOMANY);
+ }
+ }
+
+ if (!SetConsoleTitle(titlebuf) ) {
+ make_err_str(GetLastError(),errbuf,128);
+ (void)StringCbPrintf(err2,sizeof(err2),"%s",v[k]);
+ stderror(ERR_SYSTEM,err2,errbuf);
+ }
+ cleanup_until((Char **)v);
+ return;
+}
+void docls(Char **vc, struct command *c) {
+ UNREFERENCED_PARAMETER(vc);
+ UNREFERENCED_PARAMETER(c);
+ NT_ClearScreen_WholeBuffer();
+}
+int nt_feed_to_cmd(char *file,char **argv) {
+
+ char *ptr, *orig;
+ char cmdbuf[128];
+ HANDLE htemp;
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ if (!file)
+ return 1;
+
+ ptr = strrchr(file,'.');
+
+ if(!ptr)
+ return 1;
+
+ if (lstrlen(ptr) <4)
+ return 1;
+
+ if ( _stricmp(ptr,".bat") && _stricmp(ptr,".cmd") )
+ return 1;
+
+
+ memset(&si,0,sizeof(si));
+ memset(&pi,0,sizeof(pi));
+
+ si.cb = sizeof(si);
+ si.dwFlags = STARTF_USESTDHANDLES;
+ htemp= (HANDLE)_get_osfhandle(0);
+ DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(),
+ &si.hStdInput,0,TRUE,DUPLICATE_SAME_ACCESS);
+ htemp= (HANDLE)_get_osfhandle(1);
+ DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(),
+ &si.hStdOutput,0,TRUE,DUPLICATE_SAME_ACCESS);
+ htemp= (HANDLE)_get_osfhandle(2);
+ DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(),
+ &si.hStdError,0,TRUE,DUPLICATE_SAME_ACCESS);
+
+
+ ptr =file;
+ while(*ptr) {
+ if (*ptr == '/')
+ *ptr = '\\';
+ ptr++;
+ }
+ if (gdwPlatform == VER_PLATFORM_WIN32_WINDOWS){
+ (void)StringCbPrintf(cmdbuf,sizeof(cmdbuf),
+ "command.com /c %s",file);
+ }
+ else
+ (void)StringCbPrintf(cmdbuf,sizeof(cmdbuf),
+ "cmd /c %s",file);
+
+ argv++;
+ ptr = &cmdbuf[0] ;
+ orig = ptr;
+ while(*argv) {
+ StringCbCat(ptr,sizeof(cmdbuf) - (orig - ptr), " ");
+ StringCbCat(ptr,sizeof(cmdbuf) - (orig - ptr),*argv);
+ argv++;
+ }
+
+ ptr = fix_path_for_child();
+
+ if (!CreateProcess(NULL,
+ cmdbuf,
+ NULL,
+ NULL,
+ TRUE,
+ 0,//CREATE_NEW_CONSOLE |CREATE_NEW_PROCESS_GROUP,
+ NULL,
+ NULL,
+ &si,
+ &pi) ){
+ restore_path(ptr);
+ }
+ else {
+
+ restore_path(ptr);
+ CloseHandle(pi.hThread);
+ WaitForSingleObject(pi.hProcess,INFINITE);
+ CloseHandle(pi.hProcess);
+ ExitProcess(0);
+ }
+
+ return 1; /*NOTREACHED*/
+}
+static char *hb_subst_array[20] ;
+void init_hb_subst(void) {
+ int i= 0;
+ size_t len;
+ char envbuf[1024];
+ char *ptr;
+ char *p2;
+
+ envbuf[0]=0;
+
+ GetEnvironmentVariable("TCSHSUBSTHB",envbuf,1024);
+
+ ptr = &envbuf[0];
+
+ if (!*ptr)
+ return;
+
+ p2 = ptr;
+
+ while (*ptr) {
+ if (*ptr == ';') {
+ len = ptr - p2;
+ if (!len){
+ ptr++;
+ continue;
+ }
+ hb_subst_array[i] = heap_alloc(len+1);
+ StringCbCopy(hb_subst_array[i],len + 1, p2);
+
+ i++;
+ p2 = ptr+1;
+ }
+ ptr++;
+ }
+}
+char *hb_subst(char *orig) {
+ int i, match;
+ char *p1;
+
+ for(i =0 ;i <20; i++) {
+ p1 = hb_subst_array[i];
+ if (!p1)
+ continue;
+ while(*p1 != ' ')
+ p1++;
+
+ *p1 = 0;
+ match = !_stricmp(orig,hb_subst_array[i]);
+ *p1 = ' ';
+ if (match){
+ return (p1+1);
+ }
+ }
+ return NULL;
+
+}
+typedef BOOL (__stdcall *shell_ex_func)(LPSHELLEXECUTEINFO);
+
+/* DO NOT initialize these here -amol */
+static HMODULE hShellDll;
+static shell_ex_func pShellExecuteEx;
+int __nt_only_start_exes;
+
+static char no_assoc[256]; //the environment string/*FIXBUF*/
+static char *no_assoc_array[20]; // the list of extensions to NOT try /*FIXBUF*/
+// explorer associations for
+
+void init_shell_dll(void) {
+
+ int rc,i;
+ size_t len;
+ char *p2, *ptr;
+
+ if (!hShellDll) {
+ hShellDll = LoadLibrary("Shell32.dll");
+ if (hShellDll) {
+ pShellExecuteEx = (shell_ex_func)GetProcAddress(
+ hShellDll,
+ "ShellExecuteEx");
+ }
+ }
+ rc=GetEnvironmentVariable("TCSHONLYSTARTEXES",no_assoc,256) ;
+ if (!rc || (rc > 255))
+ return;
+
+ if (rc == 1) {
+ __nt_only_start_exes = 1;
+ return;
+ }
+
+ ptr = &no_assoc[0];
+ i = 0;
+
+ if (!ptr)
+ return;
+
+ p2 = ptr;
+
+ while (i < 20) {
+ if (*ptr == ';' || (!*ptr)) {
+ len = ptr - p2;
+ if (!len){
+ ptr++;
+ continue;
+ }
+ no_assoc_array[i] = heap_alloc(len+1);
+ StringCbCopy(no_assoc_array[i],len+1, p2);
+ dprintf("no_assoc array %d inited to %s\n",i,no_assoc_array[i]);
+
+ i++;
+ p2 = ptr+1;
+ }
+ if (!*ptr)
+ break;
+ ptr++;
+ }
+#if NTDBG
+ for(i=0;i<20,no_assoc_array[i] != NULL;i++)
+ dprintf("no_assoc array %d inited remains %s\n",i,no_assoc_array[i]);
+#endif NTDBG
+
+}
+// return non-zero if str is found in no_assoc_array
+int find_no_assoc(char *my_str) {
+ int i, match;
+ char *p1;
+
+ for(i =0 ;i <20; i++) {
+ p1 = no_assoc_array[i];
+ dprintf("no_assoc array %d is %s\n",i,no_assoc_array[i]);
+ if (!p1)
+ continue;
+ match = !_stricmp(my_str,no_assoc_array[i]);
+ if (match)
+ return 1;
+ }
+ return 0;
+}
+void try_shell_ex(char **argv,int exitsuccess, BOOL throw_ok) {/*FIXRESET*/
+
+ char *prog;
+ char *cmdstr, *p2, *cmdend;
+ char *originalPtr = NULL;
+ unsigned int cmdsize,cmdlen;
+ char err2[256];
+ char *ptr;
+ SHELLEXECUTEINFO shinfo;
+ unsigned long mask = SEE_MASK_FLAG_NO_UI;
+ BOOL rc;
+ char *extension;
+
+ prog=*argv;
+
+ dprintf("trying shellex for prog %s\n",prog);
+ ptr = prog;
+ if (!is_url(prog)) {
+
+ while(*ptr) {
+ if (*ptr == '/')
+ *ptr = '\\';
+ ptr++;
+ }
+
+ extension = ptr;
+
+ // search back for "."
+ while(extension != prog) {
+ if (*extension == '.') {
+ extension++;
+ break;
+ }
+ else
+ extension--;
+ }
+ /* check if this matches a member in the no_assoc array.
+ */
+ if (extension != prog) {
+ if (find_no_assoc(extension))
+ return;
+ }
+
+ }
+ originalPtr = cmdstr= heap_alloc(MAX_PATH<<2);
+
+ cmdsize = MAX_PATH<<2;
+
+ p2 = cmdstr;
+
+ cmdlen = 0;
+ cmdend = p2;
+
+ argv++; // the first arg is the command
+
+
+ dprintf("try_shell_ex calling c_a_a_q");
+ if(!concat_args_and_quote(argv,&originalPtr,&cmdstr,&cmdlen,&cmdend,&cmdsize))
+ {
+ errno = ENOMEM;
+ heap_free(originalPtr);
+ return;
+ }
+
+ *cmdend = 0;
+
+
+ memset(&shinfo,0,sizeof(shinfo));
+ shinfo.cbSize = sizeof(shinfo);
+ shinfo.fMask = SEE_MASK_FLAG_DDEWAIT | mask;
+ shinfo.hwnd = NULL;
+ shinfo.lpVerb = NULL;
+ shinfo.lpFile = prog;
+ shinfo.lpParameters = &cmdstr[0];
+ shinfo.lpDirectory = 0;
+ shinfo.nShow = SW_SHOWDEFAULT;
+
+
+ ptr = fix_path_for_child();
+
+ rc = pShellExecuteEx(&shinfo);
+ if (rc ) {
+ if (exitsuccess)
+ ExitProcess(0);
+ errno = 0;
+
+ heap_free(originalPtr);
+ return;
+ }
+ if (throw_ok) {
+ // if we got here, ShellExecuteEx failed, so reset() via stderror()
+ // this may cause the caller to leak, but the assumption is that
+ // only a child process sets exitsuccess, so it will be dead soon
+ // anyway
+
+ restore_path(ptr);
+
+ make_err_str(GetLastError(),cmdstr,512);//don't need the full size
+ (void)StringCbPrintf(err2,sizeof(err2),"%s",prog);
+ stderror(ERR_SYSTEM,err2,cmdstr);/*FIXRESET*/
+ }
+
+ heap_free(originalPtr);
+ restore_path(ptr);
+
+ errno = ENOEXEC;
+
+}
+#ifdef NTDBG
+void dodebugbreak(Char **vc, struct command *c) {
+ UNREFERENCED_PARAMETER(vc);
+ UNREFERENCED_PARAMETER(c);
+ DebugBreak();
+}
+#endif NTDBG
+int nt_texec(char *, char**) ;
+static Char *epath;
+static Char *abspath[] = {STRNULL,0};
+int nt_try_fast_exec(struct command *t) {
+ register Char **pv, **av;
+ register Char *dp,*sav;
+ register char **tt;
+ register char *f;
+ register struct varent *v;
+ register int hashval,i;
+ register int slash;
+ int rc = 0, gflag;
+ Char *vp;
+ Char *blk[2];
+
+ vp = varval(STRNTslowexec);
+ if (vp != STRNULL)
+ return 1;
+
+ blk[0] = t->t_dcom[0];
+ blk[1] = 0;
+
+ // don't do backtick
+ if(Strchr(t->t_dcom[0],'`') )
+ return 1;
+
+
+ gflag = tglob(blk);
+ if (gflag) {
+ pv = globall(blk, gflag);
+ if (pv == 0) {
+ return 1;
+ }
+ }
+ else
+ pv = saveblk(blk);
+
+ trim(pv);
+
+ epath = Strsave(pv[0]);
+ v = adrof(STRpath);
+ if (v == 0 && epath[0] != '/' && epath[0] != '.') {
+ blkfree(pv);
+ return 1;
+ }
+ slash = any(short2str(epath),'/');
+ /*
+ * Glob the argument list, if necessary. Otherwise trim off the quote bits.
+ */
+ av = &t->t_dcom[1];
+ gflag = tglob(av);
+ if (gflag) {
+ av = globall(av, gflag);/*FIXRESET*/
+ if (av == 0) {
+ blkfree(pv);
+ return 1;
+ }
+ }
+ else
+ av = saveblk(av);
+
+ blkfree(t->t_dcom);
+ t->t_dcom = blkspl(pv, av);
+ xfree((ptr_t) pv);
+ xfree((ptr_t) av);
+ av = t->t_dcom;
+ //trim(av);
+
+ if (*av == NULL || **av == '\0')
+ return 1;
+
+ xechoit(av);/*FIXRESET*/ /* Echo command if -x */
+ if (v == 0 || v->vec[0] == 0 || slash)
+ pv = abspath;
+ else
+ pv = v->vec;
+
+ sav = Strspl(STRslash,*av);
+ hashval = hashval_extern(*av);
+
+ i = 0;
+ do {
+#pragma warning(disable:4310)
+ if (!slash && ABSOLUTEP(pv[0]) && havhash) {
+#pragma warning(default:4310)
+ if (!bit_extern(hashval,i)){
+ pv++;i++;
+ continue;
+ }
+ }
+ if (pv[0][0] == 0 || eq(pv[0],STRdot)) {
+
+ tt = short2blk(av);
+ f = short2str(*av);
+
+ rc = nt_texec(f, tt);
+
+ blkfree((Char**)tt);
+ if (!rc)
+ break;
+ }
+ else {
+ dp = Strspl(*pv,sav);
+ tt = short2blk(av);
+ f = short2str(dp);
+
+ rc = nt_texec(f, tt);
+
+ blkfree((Char**)tt);
+ xfree((ptr_t)dp);
+ if (!rc)
+ break;
+ }
+ pv++;
+ i++;
+ }while(*pv);
+ return rc;
+}
+int nt_texec(char *prog, char**args ) {
+
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ HANDLE htemp;
+ DWORD type=0;
+ DWORD dwCreationflags;
+ unsigned int priority;
+ char *argv0 = NULL, *savepath = NULL;
+ char *cmdstr,*cmdend ;
+ char *originalPtr = NULL;
+ unsigned int cmdsize,cmdlen;
+ char *p2;
+ char **savedargs;
+ int retries=0;
+ int hasdot =0;
+ int is_winnt=0;
+ int retval = 1;
+
+ memset(&si,0,sizeof(si));
+ savedargs = args;
+
+ /* MUST FREE !! */
+ originalPtr = cmdstr= heap_alloc(MAX_PATH<<2);
+ cmdsize = MAX_PATH<<2;
+
+ is_winnt = (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS);
+
+
+ p2 = cmdstr;
+
+ cmdlen = 0;
+ cmdlen += copy_quote_and_fix_slashes(prog,cmdstr,&hasdot);
+ p2 += cmdlen;
+
+ if (*cmdstr != '"') {
+ // If not quoted, skip initial character we left for quote
+ *cmdstr = 'A';
+ cmdstr++;
+ cmdsize--;
+ }
+ *p2 = 0;
+ cmdend = p2;
+
+ if (!is_winnt) {
+ argv0 = NULL;
+ }
+ else {
+ argv0= heap_alloc(MAX_PATH);
+ (void)StringCbPrintf(argv0,MAX_PATH,"%s",prog);
+ }
+
+ si.cb = sizeof(STARTUPINFO);
+ si.dwFlags = STARTF_USESTDHANDLES;
+ htemp= (HANDLE)_get_osfhandle(SHIN);
+ DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(),
+ &si.hStdInput,0,TRUE,DUPLICATE_SAME_ACCESS);
+ htemp= (HANDLE)_get_osfhandle(SHOUT);
+ DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(),
+ &si.hStdOutput,0,TRUE,DUPLICATE_SAME_ACCESS);
+ htemp= (HANDLE)_get_osfhandle(SHDIAG);
+ DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(),
+ &si.hStdError,0,TRUE,DUPLICATE_SAME_ACCESS);
+
+
+ /*
+ quotespace hack needed since execv() would have separated args, but
+ createproces doesnt
+ -amol 9/14/96
+ */
+
+ args++; // the first arg is the command
+
+ dprintf("nt_texec calling c_a_a_q");
+ if(concat_args_and_quote(args,&originalPtr,&cmdstr,&cmdlen,&cmdend,&cmdsize) == NULL)
+ {
+ retval = 1;
+ errno = ENOMEM;
+ heap_free(originalPtr);
+ goto free_mem;
+ }
+
+ *cmdend = 0;
+
+ dwCreationflags = GetPriorityClass(GetCurrentProcess());
+ priority = GetThreadPriority(GetCurrentThread());
+
+ if (is_winnt) {
+ retries = 0;
+ // For NT, try ShellExecuteEx first
+ do {
+ if (GetBinaryType(argv0,&type))
+ break;
+ if (GetLastError() == ERROR_BAD_EXE_FORMAT){
+ errno = ENOEXEC;
+ if (!__nt_only_start_exes)
+ try_shell_ex(savedargs,0,FALSE);
+ if (errno) {
+ retval = 1;
+ goto free_mem;
+ }
+ else {
+ retval = 0;
+ goto free_mem;
+ }
+ }
+ // only try shellex again after appending ".exe fails
+ else if ( retries > 1 ){
+ if (
+ ( (argv0[0] == '\\') ||(argv0[0] == '/') ) &&
+ ( (argv0[1] == '\\') ||(argv0[1] == '/') ) &&
+ (!args[1])
+ )
+ if (!__nt_only_start_exes)
+ try_shell_ex(savedargs,0,FALSE);
+ errno = ENOENT;
+ }
+ if (retries == 0)
+ (void)StringCbPrintf(argv0,MAX_PATH,"%s.exe",prog);
+ else if (retries == 1) {
+ (void)StringCbPrintf(argv0,MAX_PATH,"%s.EXE",prog);
+ }
+ retries++;
+ }while(retries < 3);
+ }
+ savepath = fix_path_for_child();
+re_cp:
+ dprintf("nt_texec cmdstr %s\n",cmdstr);
+
+
+ if (!CreateProcess(argv0,
+ cmdstr,
+ NULL,
+ NULL,
+ TRUE, // need this for redirecting std handles
+ dwCreationflags,
+ NULL,//envcrap,
+ NULL,
+ &si,
+ &pi) ){
+
+ if (GetLastError() == ERROR_BAD_EXE_FORMAT) {
+ errno = ENOEXEC;
+ }
+ else if (GetLastError() == ERROR_INVALID_PARAMETER) {
+ errno = ENAMETOOLONG;
+ }else {
+ errno = ENOENT;
+ }
+ if (!is_winnt && !hasdot) { //append '.' to the end if needed
+ StringCbCat(cmdstr,cmdsize,".");
+ hasdot=1;
+ goto re_cp;
+ }
+ retval = 1;
+ }
+ else{
+ int gui_app ;
+ DWORD exitcode;
+ char guivar[50];
+
+
+ if (GetEnvironmentVariable("TCSH_NOASYNCGUI",guivar,50))
+ gui_app=0;
+ else
+ gui_app= is_gui(argv0);
+
+ if(!gui_app) {
+ WaitForSingleObject(pi.hProcess,INFINITE);
+ (void)GetExitCodeProcess(pi.hProcess,&exitcode);
+ setv(STRstatus, putn(exitcode), VAR_READWRITE);/*FIXRESET*/
+ }
+ retval = 0;
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ }
+free_mem:
+ CloseHandle(si.hStdInput);
+ CloseHandle(si.hStdOutput);
+ CloseHandle(si.hStdError);
+
+ if(savepath)
+ restore_path(savepath);
+
+ heap_free(originalPtr);
+ if (argv0)
+ heap_free(argv0);
+ return retval;
+}
+BOOL is_url(const char *thecmd) {
+ char *protocol;
+ const char *c;
+ HKEY hkey;
+ char buf[2];
+ DWORD type;
+ DWORD size;
+
+ c = strchr(thecmd, ':');
+ size = (DWORD)(c - thecmd);
+ if (!c || size <= 1)
+ return FALSE;
+
+ protocol = (char *)heap_alloc(size + 2);
+ StringCbCopy(protocol,size+2, thecmd);
+ protocol[size] = '\0';
+
+ if (RegOpenKeyEx(HKEY_CLASSES_ROOT, protocol, 0, KEY_READ, &hkey)
+ != ERROR_SUCCESS ) {
+ heap_free(protocol);
+ return FALSE;
+ }
+
+ heap_free(protocol);
+
+ type = REG_SZ;
+ size = sizeof(buf);
+ if ( RegQueryValueEx(hkey, "URL Protocol", NULL, &type, (BYTE*)buf, &size)
+ != ERROR_SUCCESS) {
+ RegCloseKey(hkey);
+ return FALSE;
+ }
+ RegCloseKey(hkey);
+ return TRUE;
+}
+/*
+ * patch based on work by Chun-Pong Yu (bol.pacific.net.sg)
+ */
+BOOL is_nt_executable(char *path,char *extension) {
+ DWORD exetype;
+
+ if (GetBinaryType(path,&exetype))
+ return TRUE;
+ if (*extension && find_no_assoc(extension))
+ return TRUE;
+
+ return FALSE;
+}
+int executable(const Char *dir, const Char *name, int dir_ok)
+{
+ struct stat stbuf;
+ Char path[MAXPATHLEN + 1];
+ char *strname;
+ char extension[MAXPATHLEN];
+ char *ptr, *p2 ;
+ int has_ext = 0;
+ extern void copyn(Char *, const Char *, size_t);
+ extern void catn(Char *, const Char *, int);
+
+ (void) memset(path, 0, sizeof(path));
+
+ if (dir && *dir) {
+ copyn(path, dir, MAXPATHLEN);
+ catn(path, name, MAXPATHLEN);
+
+ p2 = ptr = short2str(path);
+
+ while (*ptr++)
+ continue;
+ --ptr;
+
+ while(ptr > p2) {
+ if (*ptr == '/')
+ break;
+ if (*ptr == '.') {
+ has_ext = 1;
+ StringCbCopy(extension,MAXPATHLEN,ptr+1);
+ break;
+ }
+ ptr--;
+ }
+ if (!has_ext && (nt_stat(p2, &stbuf) == -1))
+ catn(path, STRdotEXE, MAXPATHLEN);
+ strname = short2str(path);
+ }
+ else
+ strname = short2str(name);
+
+ return (stat(strname, &stbuf) != -1 &&
+ ((dir_ok && S_ISDIR(stbuf.st_mode)) ||
+ (S_ISREG(stbuf.st_mode) &&
+ (is_nt_executable(strname,extension) ||
+ (stbuf.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR)))
+ )));
+}
+ int
+nt_check_if_windir(char *path)
+{
+ char windir[MAX_PATH];
+
+ (void)GetWindowsDirectory(windir, sizeof(windir));
+ windir[2] = '/';
+
+ return (strstr(path, windir) != NULL);
+}
+
+ void
+nt_check_name_and_hash(int is_windir, char *file, int i)
+{
+ char name_only[MAX_PATH];
+ char *tmp = (char *)strrchr(file, '.');
+ char uptmp[5], *nameptr, *np2;
+ int icount, hashval;
+
+ if(!tmp || tmp[4])
+ goto nodot;
+
+ for (icount = 0; icount < 4; icount++)
+ uptmp[icount] = (char)toupper(tmp[icount]);
+ uptmp[4]=0;
+
+ if (is_windir)
+ if((uptmp[1] != 'E') || (uptmp[2] != 'X') || (uptmp[3] != 'E'))
+ return;
+ (void) memset(name_only, 0, MAX_PATH);
+ nameptr = file;
+ np2 = name_only;
+ while(nameptr != tmp) {
+ *np2++= (char)tolower(*nameptr);
+ nameptr++;
+ }
+ hashval = hashname(str2short(name_only));
+ bis_extern(hashval, i);
+nodot:
+ hashval = hashname(str2short(file));
+ bis_extern(hashval, i);
+}
diff --git a/win32/ntport.h b/win32/ntport.h
new file mode 100644
index 000000000000..d78fbf684a51
--- /dev/null
+++ b/win32/ntport.h
@@ -0,0 +1,511 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/ntport.h,v 1.14 2010/05/23 17:20:32 amold Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+// ntport.h
+// the main header.
+// -amol
+//
+//
+#ifndef NTPORT_H
+#define NTPORT_H
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <io.h>
+#include <direct.h>
+#include "dirent.h"
+#include "version.h"
+
+#ifndef WINDOWS_ONLY
+#define STRSAFE_NO_DEPRECATE
+#endif /* WINDOWS_ONLY*/
+#define STRSAFE_LIB
+#define STR_NO_CCH_FUNCTIONS
+#include <strsafe.h>
+
+// These needed for fork(), which controls the heap management.
+#pragma data_seg(".fusrdata")
+#define INIT_ZERO =0
+#define INIT_ZERO_STRUCT ={0}
+#define malloc fmalloc
+#define calloc fcalloc
+#define realloc frealloc
+#define free ffree
+#undef min
+#undef max
+
+#define heap_alloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))
+#define heap_free(p) HeapFree(GetProcessHeap(),0,(p))
+#define heap_realloc(p,s) HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(p),(s))
+
+#pragma warning(disable:4018) //signed-unsigned mismatch
+#define HAVENOLIMIT
+
+/* os-dependent stuff. belongs in tc.os.h, but I never said this would be
+pretty */
+
+#define lstat stat
+#ifdef S_IFMT
+# if !defined(S_ISDIR) && defined(S_IFDIR)
+# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
+# endif /* ! S_ISDIR && S_IFDIR */
+# if !defined(S_ISCHR) && defined(S_IFCHR)
+# define S_ISCHR(a) (((a) & S_IFMT) == S_IFCHR)
+# endif /* ! S_ISCHR && S_IFCHR */
+# if !defined(S_ISBLK) && defined(S_IFBLK)
+# define S_ISBLK(a) (((a) & S_IFMT) == S_IFBLK)
+# endif /* ! S_ISBLK && S_IFBLK */
+# if !defined(S_ISREG) && defined(S_IFREG)
+# define S_ISREG(a) (((a) & S_IFMT) == S_IFREG)
+# endif /* ! S_ISREG && S_IFREG */
+# if !defined(S_ISFIFO) && defined(S_IFIFO)
+# define S_ISFIFO(a) (((a) & S_IFMT) == S_IFIFO)
+# endif /* ! S_ISFIFO && S_IFIFO */
+# if !defined(S_ISNAM) && defined(S_IFNAM)
+# define S_ISNAM(a) (((a) & S_IFMT) == S_IFNAM)
+# endif /* ! S_ISNAM && S_IFNAM */
+# if !defined(S_ISLNK) && defined(S_IFLNK)
+# define S_ISLNK(a) (((a) & S_IFMT) == S_IFLNK)
+# endif /* ! S_ISLNK && S_IFLNK */
+# if !defined(S_ISSOCK) && defined(S_IFSOCK)
+# define S_ISSOCK(a) (((a) & S_IFMT) == S_IFSOCK)
+# endif /* ! S_ISSOCK && S_IFSOCK */
+#endif /* S_IFMT */
+
+/* port defines */
+#define getpid GetCurrentProcessId
+#define getpgrp GetCurrentProcessId
+#define tcgetpgrp(a) GetCurrentProcessId()
+#define tcsetpgrp(a,b) 0
+#define setpgid(a,b) 0
+
+
+#define close(a) nt_close(a)
+#define execv(a,b) nt_exec((a),(b))
+#define execve(a,b,c) nt_execve((a),(b),(c))
+
+#define open nt_open
+#define read(f,b,n) nt_read((f),(b),(n))
+#define write(f,b,n) nt_write((f),(b),(n))
+#define creat(f,m) nt_creat((f),(m))
+#define _exit(a) ExitProcess((a))
+
+#define chdir(a) nt_chdir(a)
+
+#undef putc
+#undef putchar
+#define fgetc(a) nt_fgetc(a)
+#define fputs(a,b) nt_fputs((a),(b))
+#define putc(a,b) nt_putc((char)(a),(b))
+#define fflush(a) nt_fflush((a))
+#define fputc(a,b) nt_fputc((char)(a),(b))
+#define fprintf nt_fprintf
+#define puts(a) nt_puts(a)
+#define putchar(a) nt_putchar((char)(a))
+#define fclose(p) nt_fclose(p)
+#define _get_osfhandle __nt_get_osfhandle
+#define _open_osfhandle __nt_open_osfhandle
+#define clearerr nt_clearerr
+#define dup2 nt_dup2
+#define fdopen nt_fdopen
+#define fgets nt_fgets
+#define fileno nt_fileno
+#define fopen nt_fopen
+#define fread nt_fread
+#define fseek nt_fseek
+#define ftell nt_ftell
+#define fwrite nt_fwrite
+#define isatty nt_isatty
+#define lseek nt_lseek
+#define printf nt_printf
+#define access nt_access
+#define fstat(a,b) nt_fstat((a),(b))
+#define stat(a,b) nt_stat((a),(b))
+
+#define setvbuf(a,b,c,d)
+#define setpgrp(a,b) (-1)
+#define tcsetattr(a,b,c) 0
+
+#define inline __inline
+
+#undef stdin
+#undef stdout
+#undef stderr
+#define stdin ((FILE*)my_stdin)
+#define stdout ((FILE*)my_stdout)
+#define stderr ((FILE*)my_stderr)
+
+#define dup(f) nt_dup((f))
+#define sleep(a) Sleep((a)*1000)
+
+#define getcwd(a,b) forward_slash_get_cwd((a),(b))
+
+
+#define L_SET SEEK_SET
+#define L_XTND SEEK_END
+#define L_INCR SEEK_CUR
+#define S_IXUSR S_IEXEC
+#define S_IXGRP S_IEXEC
+#define S_IXOTH S_IEXEC
+
+#define NOFILE 64
+#define ARG_MAX 1024
+#define MAXSIG NSIG
+
+/*
+mode Value Checks File For
+
+00 Existence only
+02 Write permission
+04 Read permission
+06 Read and write permission
+*/
+#define F_OK 0
+#define X_OK 1
+#define W_OK 2
+#define R_OK 4
+#define XD_OK 9 //executable and not directory
+
+/* base key mappings + ctrl-key mappings + alt-key mappings */
+/* see nt.bind.c to figure these out */
+/* 256 +
+ 4*24 (fkeys) +
+ 4*4 (arrow) +
+ 4*2 (pgup/dn) +
+ 4*2 (home/end) +
+ 4*2 (ins/del)
+*/
+#define NT_NUM_KEYS 392
+
+#define NT_SPECIFIC_BINDING_OFFSET 256 /* where our bindings start */
+
+#define KEYPAD_MAPPING_BEGIN 24 /* offset from NT_SPECIFIC
+ where keypad mappings begin */
+#define INS_DEL_MAPPING_BEGIN 32
+
+#define SINGLE_KEY_OFFSET 0 /*if no ctrl or alt pressed */
+#define CTRL_KEY_OFFSET 34
+#define ALT_KEY_OFFSET (34*2)
+#define SHIFT_KEY_OFFSET (34*3)
+
+typedef int pid_t;
+typedef int speed_t;
+typedef unsigned char u_char;
+typedef size_t caddr_t;
+typedef int sig_atomic_t;
+typedef int mode_t;
+typedef UINT32 uint32_t;
+
+struct timeval{
+ long tv_sec;
+ long tv_usec;
+};
+struct termios;
+/*
+struct timezone{
+ int tz_minuteswest;
+ int dsttime;
+};
+*/
+struct rusage {
+
+ struct timeval ru_utime; /* user time used */
+ struct timeval ru_stime; /* system time used */
+ long ru_maxrss; /* maximum resident set size */
+ long ru_ixrss; /* integral shared memory size */
+ long ru_idrss; /* integral unshared data size */
+ long ru_isrss; /* integral unshared stack size */
+ long ru_minflt; /* page reclaims */
+ long ru_majflt; /* page faults */
+ long ru_nswap; /* swaps */
+ long ru_inblock; /* block input operations */
+ long ru_oublock; /* block output operations */
+ long ru_msgsnd; /* messages sent */
+ long ru_msgrcv; /* messages received */
+ long ru_nsignals; /* signals received */
+ long ru_nvcsw; /* voluntary context switches */
+ long ru_nivcsw; /* involuntary context switches */
+};
+typedef int uid_t;
+typedef int gid_t;
+typedef long ssize_t;
+
+struct passwd {
+ char *pw_name; /* user name */
+ char *pw_passwd; /* user password */
+ uid_t pw_uid; /* user id */
+ gid_t pw_gid; /* group id */
+ char *pw_gecos; /* real name */
+ char *pw_dir; /* home directory */
+ char *pw_shell; /* shell program */
+};
+struct group {
+ char *gr_name; /* group name */
+ char *gr_passwd; /* group password */
+ gid_t gr_gid; /* group id */
+ char **gr_mem; /* group members */
+};
+
+#ifndef _INTPTR_T_DEFINED
+#ifdef _WIN64
+typedef __int64 intptr_t;
+#else
+typedef int intptr_t;
+#endif
+#define _INTPTR_T_DEFINED
+#endif
+/* ntport.c */
+extern char * ttyname(int);
+extern struct passwd* getpwuid(uid_t ) ;
+extern struct group * getgrgid(gid_t ) ;
+extern struct passwd* getpwnam(const char* ) ;
+extern struct group* getgrnam(char* ) ;
+extern gid_t getuid(void) ;
+extern gid_t getgid(void) ;
+extern gid_t geteuid(void) ;
+extern gid_t getegid(void) ;
+
+#ifdef NTDBG
+extern void dprintf(char *,...);
+#define DBreak() __asm {int 3}
+#else
+#define dprintf (void)
+#endif NTDBG
+
+#define pipe(a) nt_pipe(a)
+
+
+/* support.c */
+extern void nt_init(void);
+extern int gethostname(char*,int);
+extern char* forward_slash_get_cwd(char *,size_t len );
+extern int nt_chdir(char*);
+extern void nt_execve(char *,char**,char**);
+extern void nt_exec(char *,char**);
+extern int quoteProtect(char *, char *,unsigned long) ;
+extern char* fix_path_for_child(void) ;
+extern void restore_path(char *) ;
+extern int copy_quote_and_fix_slashes(char *,char *, int * );
+extern char* concat_args_and_quote(char **,char**,char **,unsigned int *, char **,
+ unsigned int *) ;
+
+
+extern int is_nt_executable(char*,char*);
+/* io.c */
+extern int force_read(int, unsigned char*,size_t);
+extern int nt_read(int, unsigned char*,size_t);
+extern int nt_write(int, const unsigned char*,size_t);
+extern int stringtable_read(int,char*,size_t);
+
+/* tparse.c */
+extern int tc_putc(char,FILE*);
+
+
+void nt_cleanup(void);
+
+/* stdio.c */
+extern int nt_creat(const char*,int);
+extern int nt_close(int);
+extern int nt_open(const char*,int ,...);
+extern int nt_pipe(int*);
+extern void restore_fds(void ) ;
+extern void copy_fds(void);
+extern void close_copied_fds(void ) ;
+extern int nt_fgetc(FILE*);
+extern int nt_dup(int);
+extern int nt_fputs(char*,FILE*);
+extern int nt_putc(char,FILE*);
+extern int nt_fflush(FILE*);
+extern int nt_fputc(char, FILE*);
+extern int nt_fprintf(FILE*,char*,...);
+extern int nt_puts(char*);
+extern int nt_putchar(char);
+extern int nt_fclose(FILE*);
+extern int nt_fputs(char *, FILE*);
+extern intptr_t __nt_get_osfhandle(int);
+extern int __nt_open_osfhandle(intptr_t, int);
+extern int nt_clearerr(FILE*);
+extern int nt_dup2(int,int );
+extern FILE* nt_fdopen(int,char*);
+extern char * nt_fgets(char *,int, FILE*);
+extern int nt_fileno(FILE*);
+extern FILE *nt_fopen(char *,char*);
+extern int nt_fread(void *,size_t,size_t,FILE*);
+extern int nt_fwrite(void*,size_t,size_t,FILE*);
+extern int nt_fseek(FILE*,long,int);
+extern long nt_ftell(FILE*);
+extern int nt_isatty(int);
+extern int nt_lseek(int,long,int);
+extern int nt_printf(char*,...);
+extern int nt_access(char*,int);
+extern int nt_fstat(int, struct stat *) ;
+extern int nt_stat(const char *, struct stat *) ;
+extern void nt_close_on_exec(int , int);
+extern void init_stdio(void) ;
+extern int is_resource_file(int);
+#ifndef STDIO_C
+extern void *my_stdin,*my_stdout,*my_stderr;
+#endif STDIO_C
+
+
+/* nt.char.c */
+extern unsigned char oem_it(unsigned char );
+extern char *nt_cgets(int,int,char*);
+extern void nls_dll_init(void);
+extern void nls_dll_unload(void);
+extern void nt_autoset_dspmbyte(void);
+
+/* fork.c */
+extern int fork_init(void);
+extern int fork(void);
+extern void *sbrk(int);
+extern void *fmalloc(size_t);
+extern void ffree(void *);
+extern void *frealloc(void*,size_t);
+extern void *fcalloc(size_t,size_t);
+extern void set_stackbase(void*);
+
+/* console.c */
+extern void do_nt_cooked_mode(void );
+extern void do_nt_raw_mode(void ) ;
+extern int do_nt_check_cooked_mode(void);
+extern void set_cons_attr (char *);
+extern void NT_MoveToLineOrChar(int ,int ) ;
+extern void nt_term_init(void);
+extern void nt_term_cleanup(void);
+extern void nt_set_size(int,int);
+//extern DWORD set_cooked_mode(HANDLE);
+//extern void set_raw_mode(HANDLE);
+//extern void set_arbitrary_mode(HANDLE,DWORD);
+extern void set_attributes(const unsigned char *color);
+
+/* ../sh.exec.c */
+extern int nt_check_if_windir(char *);
+extern void nt_check_name_and_hash(int ,char *,int);
+
+
+/* clip.c */
+extern void cut_clip(void);
+extern int paste_clip(void);
+extern void init_clipboard(void);
+extern HANDLE create_clip_writer_thread(void) ;
+extern HANDLE create_clip_reader_thread(void) ;
+
+/* signal.c */
+extern int kill(int,int);
+extern int nice(int);
+extern void nt_init_signals(void) ;
+extern void nt_cleanup_signals(void) ;
+extern void start_sigchild_thread(HANDLE , DWORD ) ;
+
+/* nt.who.c */
+extern void start_ncbs(short **);
+extern void cleanup_netbios(void);
+
+/* ntfunc.c */
+struct command;
+extern void dostart(short **,struct command *);
+extern void docls(short **,struct command *);
+extern void dotitle(short **, struct command * ) ;
+extern void dostacksize(short**,struct command *);
+extern void dosourceresource(short **, struct command * ) ;
+extern void doprintresource(short **, struct command * ) ;
+#ifdef NTDBG
+extern void dodebugbreak(short **, struct command * ) ;
+#endif NTDBG
+extern void nt_set_env(const short *, const short*);
+extern char *hb_subst(char *) ;
+extern void init_hb_subst() ;
+extern void init_shell_dll(void) ;
+extern void try_shell_ex(char**,int,BOOL);
+extern int nt_try_fast_exec(struct command *);
+extern int nt_feed_to_cmd(char*,char**);
+extern short nt_translate_bindkey(const short*);
+
+extern struct biltins *nt_check_additional_builtins(short *);
+extern void nt_print_builtins(size_t);
+
+/* ps.c */
+extern void init_plister(void);
+extern void dops(short **,struct command *);
+extern void doshutdown(short **,struct command *);
+extern int kill_by_wm_close(int ) ;
+
+/* globals.c */
+extern int is_gui(char*);
+extern int is_9x_gui(char*);
+
+
+/* Global variables */
+extern unsigned short __nt_want_vcode,__nt_vcode,__nt_really_exec;
+extern int __dup_stdin;
+extern int __nt_only_start_exes;
+extern unsigned short __nt_child_nohupped;
+extern DWORD gdwPlatform,gdwVersion;
+extern int is_dev_clipboard_active;
+extern HANDLE ghdevclipthread;
+extern DWORD gdwStackSize;
+
+// bogus
+#define getppid() 0
+
+struct tms {
+ clock_t tms_utime;
+ clock_t tms_stime;
+ clock_t tms_cutime;
+ clock_t tms_cstime;
+};
+#define UT_UNKNOWN 0
+#define DEAD_PROCESS 7
+#define USER_PROCESS 8
+#define UT_LINESIZE 16
+#define UT_NAMESIZE 8
+#define UT_HOSTSIZE 16
+
+struct utmp {
+ short ut_type; /* type of login */
+ pid_t ut_pid;
+ char ut_line[UT_LINESIZE]; /* device pref'/dev/' */
+ char ut_id[2]; /*abbrev tty name */
+ time_t ut_time; /* login time */
+ char ut_user[UT_NAMESIZE]; /* user name */
+ char ut_host[UT_HOSTSIZE]; /* hostname for rlogin */
+ long ut_addr; /*ipaddr of remote host */
+};
+
+
+#define ut_name ut_user
+#define killpg kill
+
+#endif NTPORT_H
diff --git a/win32/ps.c b/win32/ps.c
new file mode 100644
index 000000000000..bc81f1c954ee
--- /dev/null
+++ b/win32/ps.c
@@ -0,0 +1,371 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/ps.c,v 1.9 2006/03/14 01:22:58 mitr Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * ps.c : ps,shutdown builtins.
+ * -amol
+ *
+ */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winperf.h>
+#include <tlhelp32.h>
+#include <sh.h>
+#include <errno.h>
+
+
+#define REGKEY_PERF "software\\microsoft\\windows nt\\currentversion\\perflib"
+#define REGSUBKEY_COUNTERS "Counters"
+#define PROCESS_COUNTER "process"
+#define PROCESSID_COUNTER "id process"
+
+typedef struct _pslist {
+ DWORD pid;
+ HANDLE hwnd;
+ char exename[MAX_PATH];
+ char title[80];
+}pslist;
+
+
+typedef BOOL (WINAPI *walker)(HANDLE,LPPROCESSENTRY32);
+typedef HANDLE (WINAPI *create_snapshot)(DWORD,DWORD);
+static walker proc32First;
+static walker proc32Next;
+static create_snapshot createSnapshot;
+
+typedef BOOL (WINAPI *enumproc)(DWORD *,DWORD,DWORD *);
+typedef BOOL (WINAPI *enummod)(HANDLE,HMODULE*,DWORD,DWORD*);
+typedef DWORD(WINAPI *getfilename_ex)(HANDLE,HANDLE , char*,DWORD);
+typedef DWORD (WINAPI *getbasename)(HANDLE,HMODULE,char*,DWORD);
+static enumproc enum_processes;
+static enummod enum_process_modules;
+static getfilename_ex getfilenameex;
+static getbasename GetModuleBaseNameA;
+
+typedef DWORD (*plist_proc)(void);
+
+DWORD Win95Lister(void);
+DWORD NTLister(void);
+
+plist_proc ProcessListFunc;
+pslist *processlist;
+static unsigned long numprocs, g_dowindows;
+
+static HMODULE hlib;
+
+extern DWORD gdwPlatform;
+extern void make_err_str(int,char *,int);
+
+BOOL CALLBACK enum_wincb(HWND hwnd,LPARAM nump) {
+
+ unsigned int i;
+ DWORD pid = 0;
+
+ if (!GetWindowThreadProcessId(hwnd,&pid))
+ return TRUE;
+
+ for (i =0;i < nump;i++) {
+ if (processlist[i].pid == pid){
+ processlist[i].hwnd = hwnd;
+ if (processlist[i].title[0] !=0)
+ break;;
+ GetWindowText(hwnd,processlist[i].title,
+ sizeof(processlist[i].title));
+ break;
+ }
+ }
+ return TRUE;
+}
+static HWND ghwndtokillbywm_close;
+BOOL CALLBACK enum_wincb2(HWND hwnd,LPARAM pidtokill) {
+ DWORD pid = 0;
+
+ if (!GetWindowThreadProcessId(hwnd,&pid))
+ return TRUE;
+ if (pid == (DWORD)pidtokill){
+ ghwndtokillbywm_close = hwnd;
+ PostMessage( hwnd, WM_CLOSE, 0, 0 );
+ return TRUE;
+ }
+
+ return TRUE;
+}
+int kill_by_wm_close(int pid) {
+ EnumWindows(enum_wincb2,(LPARAM)pid);
+ if (!ghwndtokillbywm_close)
+ return -1;
+ ghwndtokillbywm_close = NULL;
+ return 0;
+}
+DWORD Win95Lister(void) {
+
+ HANDLE hsnap;
+ PROCESSENTRY32 pe;
+ unsigned long nump =0;
+
+
+ hsnap = createSnapshot(TH32CS_SNAPPROCESS,0);
+ if (hsnap == INVALID_HANDLE_VALUE)
+ return 0;
+
+ // if (processlist)
+ // p_free(processlist);
+
+ pe.dwSize = sizeof(PROCESSENTRY32);
+ if (proc32First(hsnap,&pe) ) {
+ processlist = heap_alloc(100*sizeof(pslist));
+ if (!processlist)
+ goto done;
+
+ do {
+ StringCbCopy(processlist[nump].exename,
+ sizeof(processlist[nump].exename),pe.szExeFile);
+
+ processlist[nump].title[0] = 0;
+ processlist[nump].pid = pe.th32ProcessID;
+ nump++;
+ }while(proc32Next(hsnap,&pe));
+ }
+done:
+ CloseHandle(hsnap);
+
+ if (g_dowindows) {
+ EnumWindows(enum_wincb,(LPARAM)nump);
+ }
+ return nump;
+}
+
+DWORD NTLister(void) {
+
+ DWORD procs[200],dummy,ignore;
+ HANDLE hproc;
+ HMODULE hmod;
+ unsigned int i;
+
+
+ // if (processlist)
+ // p_free(processlist);
+
+ if (!enum_processes(procs,sizeof(procs),&dummy) ) {
+ return 0;
+ }
+
+ dummy = dummy/sizeof(DWORD); // number of entries filled
+
+ processlist = heap_alloc(dummy*sizeof(pslist));
+ if (!processlist){
+ return 0;
+ }
+
+ for(i=0 ; i< dummy;i++) {
+ processlist[i].pid = procs[i];
+ processlist[i].title[0] = 0;
+ hproc = OpenProcess(PROCESS_QUERY_INFORMATION |PROCESS_VM_READ,
+ FALSE,procs[i]);
+ if (hproc) {
+ if (enum_process_modules(hproc,&hmod,sizeof(hmod),&ignore)) {
+ GetModuleBaseNameA(hproc,hmod, processlist[i].exename,MAX_PATH);
+ }
+ else
+ StringCbCopy(processlist[i].exename,
+ sizeof(processlist[i].exename),"(unknown)");
+ CloseHandle(hproc);
+ }
+ else
+ StringCbCopy(processlist[i].exename,
+ sizeof(processlist[i].exename),"(unknown)");
+
+ }
+ if (g_dowindows) {
+ EnumWindows(enum_wincb,(LPARAM)dummy);
+ }
+ return dummy;
+}
+
+void init_plister(void) {
+
+
+ hlib = LoadLibrary("kernel32.dll");
+ if (!hlib)
+ return ;
+
+
+ ProcessListFunc = Win95Lister;
+
+ proc32First = (walker)GetProcAddress(hlib,"Process32First");
+ proc32Next = (walker)GetProcAddress(hlib,"Process32Next");
+ createSnapshot= (create_snapshot)GetProcAddress(hlib,
+ "CreateToolhelp32Snapshot");
+
+ FreeLibrary(hlib);
+ if (!proc32First || !proc32Next || !createSnapshot) {
+ ProcessListFunc = NULL;
+ }
+}
+void dops(Char ** vc, struct command *c) {
+
+ DWORD nump;
+ unsigned int i,k;
+ char **v;
+
+ UNREFERENCED_PARAMETER(c);
+
+ if (!ProcessListFunc)
+ return;
+ vc = glob_all_or_error(vc);
+ v = short2blk(vc);
+ blkfree(vc);
+ for (k = 0; v[k] != NULL ; k++){
+ if ( v[k][0] == '-' ) {
+ if( (v[k][1] == 'W') || (v[k][1] == 'w'))
+ g_dowindows = 1;
+ }
+ }
+ blkfree((Char**)v);
+ nump = ProcessListFunc();
+
+ for(i=0; i< nump; i++) {
+ if (gdwPlatform == VER_PLATFORM_WIN32_NT)
+ xprintf("%6u %-20s %-30s\n",processlist[i].pid,
+ processlist[i].exename,
+ g_dowindows?processlist[i].title:"");
+ else
+ xprintf("0x%08x %-20s %-30s\n",processlist[i].pid,
+ processlist[i].exename,
+ g_dowindows?processlist[i].title:"");
+ }
+ g_dowindows =0;
+
+ if (processlist)
+ heap_free(processlist);
+
+}
+static char shutdown_usage[]= {"shutdown -[r|l][f] now\n-r reboots, -l logs\
+ off the current user\n-f forces termination of running applications.\n\
+ The default action is to shutdown without a reboot.\n\"now\" must be \
+ specified to actually shutdown or reboot\n"};
+
+void doshutdown(Char **vc, struct command *c) {
+
+ unsigned int flags = 0;
+ unsigned char reboot,shutdown,logoff,shutdown_ok;
+ char **v;
+ char *ptr;
+ char errbuf[128];
+ int k;
+ HANDLE hToken;
+ TOKEN_PRIVILEGES tp,tpPrevious;
+ LUID luid;
+ DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
+
+ UNREFERENCED_PARAMETER(c);
+
+ if (gdwPlatform != VER_PLATFORM_WIN32_NT) {
+ stderror(ERR_SYSTEM,"shutdown","Sorry,not supported on win95");
+ }
+
+ shutdown_ok = reboot = shutdown = logoff = 0;
+ vc = glob_all_or_error(vc);
+ v = short2blk(vc);
+ blkfree(vc);
+ cleanup_push((Char **)v, blk_cleanup);
+ for (k = 0; v[k] != NULL ; k++){
+ if ( v[k][0] == '-' ) {
+ ptr = v[k];
+ ptr++;
+ while( ptr && *ptr) {
+ if (*ptr == 'f')
+ flags |= EWX_FORCE;
+ if (*ptr == 'r')
+ reboot =1;
+ else if (*ptr == 'l')
+ logoff =1;
+ else
+ stderror(ERR_SYSTEM,"Usage",shutdown_usage);
+ ptr++;
+ }
+ }
+ else if (!_stricmp(v[k],"now")) {
+ shutdown_ok = 1;
+ }
+ }
+ if (k == 0)
+ stderror(ERR_SYSTEM,"Usage",shutdown_usage);
+ if (!reboot && !logoff){
+ flags |= EWX_SHUTDOWN;
+ shutdown = 1;
+ }
+ if (reboot && logoff )
+ stderror(ERR_SYSTEM,"Usage",shutdown_usage);
+ if (reboot)
+ flags |= EWX_REBOOT;
+ if (logoff)
+ flags |= EWX_LOGOFF;
+
+ if ((reboot || shutdown) && (!shutdown_ok) )
+ stderror(ERR_SYSTEM,"shutdown","Specify \"now\" to really shutdown");
+
+
+ if (!OpenProcessToken(GetCurrentProcess(),
+ TOKEN_ADJUST_PRIVILEGES| TOKEN_QUERY,
+ &hToken) ){
+ make_err_str(GetLastError(),errbuf,128);
+ stderror(ERR_SYSTEM,"shutdown failed",errbuf);
+ }
+
+
+ if (!LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&luid)) {
+ make_err_str(GetLastError(),errbuf,128);
+ stderror(ERR_SYSTEM,"shutdown failed",errbuf);
+ }
+ tp.PrivilegeCount = 1;
+ tp.Privileges[0].Luid = luid;
+ tp.Privileges[0].Attributes = 0;
+
+ if (!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),&tpPrevious,
+ &cbPrevious)){
+ make_err_str(GetLastError(),errbuf,128);
+ stderror(ERR_SYSTEM,"shutdown failed",errbuf);
+ }
+ tpPrevious.PrivilegeCount = 1;
+ tpPrevious.Privileges[0].Luid = luid;
+ tpPrevious.Privileges[0].Attributes |= SE_PRIVILEGE_ENABLED;
+
+ if (!AdjustTokenPrivileges(hToken,FALSE,&tpPrevious,cbPrevious,NULL,
+ NULL)){
+ make_err_str(GetLastError(),errbuf,128);
+ stderror(ERR_SYSTEM,"shutdown failed",errbuf);
+ }
+ if ( !ExitWindowsEx(flags,0) ) {
+ make_err_str(GetLastError(),errbuf,128);
+ stderror(ERR_SYSTEM,"shutdown failed",errbuf);
+ }
+ cleanup_until((Char **)v);
+}
diff --git a/win32/signal.c b/win32/signal.c
new file mode 100644
index 000000000000..facede8c40f0
--- /dev/null
+++ b/win32/signal.c
@@ -0,0 +1,728 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/signal.c,v 1.12 2010/05/13 22:04:17 amold Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * signal.c: Signal emulation hacks.
+ * -amol
+ *
+ */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "ntport.h"
+#include "forkdata.h"
+#include "signal.h"
+
+#pragma warning(disable:4055)
+
+#define SIGBAD(signo) ( (signo) <=0 || (signo) >=NSIG)
+#define fast_sigmember(a,b) ( (*(a) & (1 << (b-1)) ) )
+#define inc_pending(a) (gPending[(a)]+=1)
+
+#define suspend_main_thread() SuspendThread(hmainthr)
+#define resume_main_thread() ResumeThread(hmainthr)
+
+int generic_handler(DWORD);
+int ctrl_handler(DWORD);
+
+typedef struct _child_list {
+ DWORD dwProcessId;
+ DWORD exitcode;
+ struct _child_list *next;
+}ChildListNode;
+
+Sigfunc *handlers[NSIG]={0};
+static unsigned long gPending[NSIG]={0};
+static unsigned long gBlockMask = 0;
+
+static ChildListNode *clist_h; //head of list
+static ChildListNode *clist_t; // tail of list
+
+static CRITICAL_SECTION sigcritter;
+static HANDLE hmainthr;
+static HANDLE hsigsusp;
+static int __is_suspended = 0;
+static HANDLE __halarm=0;
+
+extern HANDLE __h_con_alarm,__h_con_int, __h_con_hup;
+
+// must be done before fork;
+void nt_init_signals(void) {
+
+ SetConsoleCtrlHandler((PHANDLER_ROUTINE)ctrl_handler,TRUE);
+ InitializeCriticalSection(&sigcritter);
+
+ clist_t = clist_h = NULL;
+
+
+ if (!DuplicateHandle(GetCurrentProcess(),
+ GetCurrentThread(),
+ GetCurrentProcess(),
+ &hmainthr,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS)){
+ ExitProcess(GetLastError());
+ }
+ hsigsusp = CreateEvent(NULL,FALSE,FALSE,NULL);
+ __h_con_alarm=CreateEvent(NULL,FALSE,FALSE,NULL);
+ __h_con_int=CreateEvent(NULL,FALSE,FALSE,NULL);
+ __h_con_hup=CreateEvent(NULL,FALSE,FALSE,NULL);
+ if (!hsigsusp)
+ abort();
+
+}
+void nt_cleanup_signals(void) {
+ if (__forked)
+ return;
+ DeleteCriticalSection(&sigcritter);
+ CloseHandle(hmainthr);
+ CloseHandle(hsigsusp);
+ CloseHandle(__h_con_alarm);
+ CloseHandle(__h_con_int);
+ CloseHandle(__h_con_hup);
+ CloseHandle(__halarm);
+}
+int sigaddset(sigset_t *set, int signo) {
+
+ if (SIGBAD(signo)) {
+ errno = EINVAL;
+ return -1;
+ }
+ *set |= 1 << (signo-1);
+ return 0;
+}
+int sigdelset(sigset_t *set, int signo) {
+ if (SIGBAD(signo)) {
+ errno = EINVAL;
+ return -1;
+ }
+ *set &= ~( 1 << (signo-1));
+
+ return 0;
+
+}
+int sigismember(const sigset_t *set, int signo) {
+ if (SIGBAD(signo)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ return ( (*set & (1 <<(signo-1)) ) != 0);
+
+}
+void deliver_pending(void) {
+ unsigned long temp;
+ int sig=1;
+
+ temp = ~gBlockMask;
+ while(temp && (sig < NSIG)) {
+
+ if (temp & 0x01){
+ if (gPending[sig]){
+ //gPending[sig]=0;
+ do {
+ dprintf("deliver_pending for sig %d\n",sig);
+ gPending[sig]--;
+ generic_handler(sig);
+ }while(gPending[sig] != 0);
+ }
+ }
+ temp >>= 1;
+ sig++;
+ }
+}
+int sigprocmask(int how, const sigset_t *set, sigset_t*oset) {
+
+ if (oset)
+ *oset = gBlockMask;
+ if (set) {
+ switch (how) {
+ case SIG_BLOCK:
+ gBlockMask |= *set;
+ break;
+ case SIG_UNBLOCK:
+ gBlockMask &= (~(*set));
+ break;
+ case SIG_SETMASK:
+ gBlockMask = *set;
+ break;
+ default:
+ break;
+ }
+ }
+ if (how != SIG_BLOCK)
+ deliver_pending();
+
+ return 0;
+
+}
+int sigsuspend(const sigset_t *mask) {
+ sigset_t omask;
+
+
+ EnterCriticalSection(&sigcritter);
+ __is_suspended++;
+ LeaveCriticalSection(&sigcritter);
+
+ sigprocmask(SIG_SETMASK,mask,&omask);
+
+ dprintf("suspending main thread susp count %d\n",__is_suspended);
+ do {
+ WaitForSingleObject(hsigsusp,INFINITE);
+ }while(__is_suspended > 0);
+
+
+ sigprocmask(SIG_SETMASK,&omask,0);
+ errno = EINTR;
+ return -1;
+
+}
+
+int sigaction(int signo, const struct sigaction *act, struct sigaction *oact) {
+
+ if (SIGBAD(signo)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if(oact){
+ oact->sa_handler = handlers[signo];
+ oact->sa_mask = 0;
+ oact->sa_flags =0;
+ }
+ if ((signo == SIGHUP) && (act && (act->sa_handler == SIG_IGN))
+ && __forked)
+ __nt_child_nohupped = 1;
+ if (act)
+ handlers[signo]=act->sa_handler;
+
+ return 0;
+
+}
+int ctrl_handler(DWORD event) {
+
+ if (event == CTRL_C_EVENT || event == CTRL_BREAK_EVENT) {
+ SetEvent(__h_con_int);
+ return TRUE;
+ }
+ if (event == CTRL_CLOSE_EVENT) {
+ SetEvent(__h_con_hup);
+ return TRUE;
+ }
+
+ return generic_handler(event+1);
+}
+int generic_handler(DWORD signo) {
+
+ int blocked=0;
+
+ if (SIGBAD(signo) )
+ return FALSE;
+ switch (signo) {
+ case SIGINT:
+ if (handlers[signo] != SIG_IGN){
+ if (fast_sigmember(&gBlockMask,signo) ) {
+ inc_pending(signo);
+ blocked=1;
+ }
+ else if (handlers[signo] == SIG_DFL)
+ ExitProcess(0xC000013AL);
+ else
+ handlers[signo](signo);
+ }
+ break;
+ case SIGBREAK:
+ if (handlers[signo] != SIG_IGN){
+ if (fast_sigmember(&gBlockMask,signo) ) {
+ inc_pending(signo);
+ blocked=1;
+ }
+ else if (handlers[signo] == SIG_DFL)
+ ExitProcess(0xC000013AL);
+ else
+ handlers[signo](signo);
+ }
+ break;
+ case SIGHUP: //CTRL_CLOSE_EVENT
+ if (handlers[signo] != SIG_IGN){
+ if (fast_sigmember(&gBlockMask,signo) ) {
+ inc_pending(signo);
+ blocked=1;
+ }
+ else if (handlers[signo] == SIG_DFL)
+ ExitProcess(604);
+ else
+ handlers[signo](signo);
+ }
+ break;
+ case SIGTERM: //CTRL_LOGOFF_EVENT
+ if (handlers[signo] != SIG_IGN){
+ if (fast_sigmember(&gBlockMask,signo) ) {
+ inc_pending(signo);
+ blocked=1;
+ }
+ else if (handlers[signo] == SIG_DFL)
+ ExitProcess(604);
+ else
+ handlers[signo](signo);
+ }
+ else
+ ExitProcess(604);
+ break;
+ case SIGKILL: //CTRL_SHUTDOWN_EVENT
+ if (handlers[signo] != SIG_IGN){
+ if (fast_sigmember(&gBlockMask,signo) ) {
+ inc_pending(signo);
+ blocked=1;
+ }
+ else if (handlers[signo] == SIG_DFL)
+ ExitProcess(604);
+ else
+ handlers[signo](signo);
+ }
+ else
+ ExitProcess(604);
+ break;
+ case SIGALRM:
+ if (handlers[signo] != SIG_IGN){
+ if (fast_sigmember(&gBlockMask,signo) ) {
+ inc_pending(signo);
+ blocked=1;
+ }
+ else if (handlers[signo] == SIG_DFL)
+ ExitProcess(604);
+ else
+ handlers[signo](signo);
+ }
+ break;
+ case SIGCHLD:
+ if (handlers[signo] != SIG_IGN){
+ if (fast_sigmember(&gBlockMask,signo) ) {
+ dprintf("inc pending for sig %d count %d\n",signo,
+ gPending[signo]);
+ inc_pending(signo);
+ blocked=1;
+ }
+ else if (handlers[signo] != SIG_DFL)
+ handlers[signo](signo);
+ }
+ break;
+ default:
+ ExitProcess(604);
+ break;
+ }
+ if (!blocked && __is_suspended) {
+ EnterCriticalSection(&sigcritter);
+ __is_suspended--;
+ LeaveCriticalSection(&sigcritter);
+ dprintf("releasing suspension is_suspsend = %d\n",__is_suspended);
+ SetEvent(hsigsusp);
+ }
+ return TRUE;
+}
+Sigfunc *_nt_signal(int signal, Sigfunc * handler) {
+
+ Sigfunc *old;
+
+ if (SIGBAD(signal)) {
+ errno = EINVAL;
+ return SIG_ERR;
+ }
+ if (signal == SIGHUP && handler == SIG_IGN && __forked) {
+ __nt_child_nohupped = 1;
+ }
+
+
+ old = handlers[signal];
+ handlers[signal] = handler;
+
+
+ return old;
+}
+int waitpid(pid_t pid, int *statloc, int options) {
+
+ ChildListNode *temp;
+ int retcode;
+
+ UNREFERENCED_PARAMETER(options);
+ errno = EINVAL;
+ if (pid != -1)
+ return -1;
+
+ EnterCriticalSection(&sigcritter);
+ if (!clist_h)
+ retcode =0;
+ else {
+ retcode = clist_h->dwProcessId;
+ if (statloc) *statloc = clist_h->exitcode;
+ temp = clist_h;
+ clist_h = clist_h->next;
+ heap_free(temp);
+ }
+ LeaveCriticalSection(&sigcritter);
+
+ errno = 0;
+ return retcode;
+
+}
+unsigned int __alarm_set=0;
+
+void CALLBACK alarm_callback( unsigned long interval) {
+
+ int rc;
+
+ rc = WaitForSingleObject(__halarm,interval*1000);
+ if (rc != WAIT_TIMEOUT)
+ return ;
+
+ SetEvent(__h_con_alarm);
+ __alarm_set = 0;
+ return;
+
+ // consoleread() now waits for above event, and calls generic_handler to
+ // handle SIGALRM in the main thread. That helps me avoid
+ // problems with fork() when we are in a secondary thread.
+ //
+ // This means sched, periodic etc will not be signalled unless consoleread
+ // is called, but that's a reasonable risk, i think.
+ // -amol 4/10/97
+
+}
+unsigned int alarm(unsigned int seconds) {
+
+ unsigned int temp;
+ static unsigned int prev_val=0;
+ HANDLE ht;
+ DWORD tid;
+ SECURITY_ATTRIBUTES secd;
+
+ secd.nLength=sizeof(secd);
+ secd.lpSecurityDescriptor=NULL;
+ secd.bInheritHandle=TRUE;
+
+
+ if (!__halarm) {
+ __halarm=CreateEvent(&secd,FALSE,FALSE,NULL);
+ }
+ if(__alarm_set )
+ SetEvent(__halarm);
+
+ if (!seconds){
+ __alarm_set=0;
+ return 0;
+ }
+ __alarm_set = 1;
+
+ ht = CreateThread(NULL,gdwStackSize,
+ (LPTHREAD_START_ROUTINE)alarm_callback,
+ (void*)UIntToPtr(seconds),
+ 0,&tid);
+ if (ht)
+ CloseHandle(ht);
+
+ temp = prev_val;
+ prev_val = seconds*1000;
+
+ return temp;
+}
+void add_to_child_list(DWORD dwpid,DWORD exitcode) {
+ if (clist_h == NULL) {
+ clist_h = heap_alloc(sizeof(ChildListNode));
+ if (!clist_h)
+ goto end;
+ clist_h->dwProcessId = dwpid;
+ clist_h->exitcode = exitcode;
+ clist_h->next= NULL;
+ clist_t = clist_h;
+ }
+ else {
+ clist_t->next = heap_alloc(sizeof(ChildListNode));
+ if (!clist_t->next)
+ goto end;
+ clist_t = clist_t->next;
+ clist_t->dwProcessId= dwpid;
+ clist_h->exitcode = exitcode;
+ clist_t->next = NULL;
+ }
+end:
+ ;
+}
+void sig_child_callback(DWORD pid,DWORD exitcode) {
+
+ DWORD ecode = 0;
+
+ EnterCriticalSection(&sigcritter);
+ add_to_child_list(pid,exitcode);
+ suspend_main_thread();
+ //
+ // pchild() tries to reset(), which crashes the thread
+ //
+ __try {
+ generic_handler(SIGCHLD);
+ }
+ __except(ecode = GetExceptionCode()) {
+ ;
+ }
+ resume_main_thread();
+ LeaveCriticalSection(&sigcritter);
+
+}
+struct thread_args {
+ DWORD pid;
+ HANDLE hproc;
+};
+void sigchild_thread(struct thread_args *args) {
+
+ DWORD exitcode=0;
+ WaitForSingleObject(args->hproc,INFINITE);
+ GetExitCodeProcess(args->hproc,&exitcode);
+ CloseHandle(args->hproc);
+ sig_child_callback(args->pid,exitcode);
+ dprintf("exiting sigchild thread for pid %d\n",args->pid);
+ heap_free(args);
+}
+void start_sigchild_thread(HANDLE hproc, DWORD pid) {
+
+ struct thread_args *args=heap_alloc(sizeof(struct thread_args));
+ DWORD tid;
+ HANDLE hthr;
+ args->hproc = hproc;
+ args->pid = pid;
+
+ dprintf("creating sigchild thread for pid %d\n",pid);
+ hthr = CreateThread(NULL,
+ gdwStackSize,
+ (LPTHREAD_START_ROUTINE)sigchild_thread,
+ (LPVOID)args,
+ 0,
+ &tid);
+
+
+ CloseHandle(hthr);
+
+}
+int kill(int pid, int sig) {
+
+ HANDLE hproc;
+ int ret =0;
+ extern DWORD gdwPlatform;
+ BOOL is_winnt = TRUE;
+
+ errno = EPERM;
+ is_winnt = (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS);
+
+ if(is_winnt) {
+ if(pid < 0)
+ {
+ if (pid == -1)
+ return -1;
+ pid = -pid; //no groups that we can actually do anything with.
+
+ }
+ }
+ else { //win9x has -ve pids
+ if(pid > 0)
+ {
+ if (pid == 1)
+ return -1;
+ pid = -pid; //no groups that we can actually do anything with.
+
+ }
+ }
+
+
+ switch(sig) {
+ case 0:
+ case 7:
+ hproc = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
+ if (hproc == NULL) {
+ errno = ESRCH;
+ ret = -1;
+ dprintf("proc %d not found\n",pid);
+ }
+ else{
+ dprintf("proc %d found\n",pid);
+ }
+ if (sig == 7) {
+ if (!TerminateProcess(hproc,0xC000013AL) ) {
+ ret = -1;
+ }
+ }
+ CloseHandle(hproc);
+ break;
+ case 1:
+ if (!GenerateConsoleCtrlEvent(CTRL_C_EVENT,pid))
+ ret = -1;
+ break;
+ case 2:
+ if (!GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,pid))
+ ret = -1;
+ break;
+ case 3:
+ if (kill_by_wm_close(pid) <0 ) {
+ errno = ESRCH;
+ ret = -1;
+ }
+ default:
+ break;
+ }
+ return ret;
+}
+//
+// nice(niceness)
+//
+// where niceness is an integer in the range -6 to +7
+//
+// A usual foreground process starts at level 9 in the chart below
+//
+// the range -6 to +7 takes it from Base priority 15 down to 2.
+//
+// Note that level 1 or > 15 are not allowed.
+//
+// Priority Level 11 (niceness -2) or greater affects system performance,
+// so use with care.
+//
+// niceness defaults to +4, which is lowest for background normal class.
+// As in unix, +ve niceness indicates lower priorities.
+
+/***************************************************************************
+Niceness Base Priority class/thread priority
+
+ 1 Idle, normal, or high class, THREAD_PRIORITY_IDLE
+
++7 2 Idle class, THREAD_PRIORITY_LOWEST
++6 3 Idle class, THREAD_PRIORITY_BELOW_NORMAL
++5 4 Idle class, THREAD_PRIORITY_NORMAL
++4 5 Background normal class, THREAD_PRIORITY_LOWEST
+ Idle class, THREAD_PRIORITY_ABOVE_NORMAL
++3 6 Background normal class, THREAD_PRIORITY_BELOW_NORMAL
+ Idle class, THREAD_PRIORITY_HIGHEST
++2 7 Foreground normal class, THREAD_PRIORITY_LOWEST
+ Background normal class, THREAD_PRIORITY_NORMAL
++1 8 Foreground normal class, THREAD_PRIORITY_BELOW_NORMAL
+ Background normal class, THREAD_PRIORITY_ABOVE_NORMAL
+ 0 9 Foreground normal class, THREAD_PRIORITY_NORMAL
+ Background normal class, THREAD_PRIORITY_HIGHEST
+-1 10 Foreground normal class, THREAD_PRIORITY_ABOVE_NORMAL
+-2 11 High class, THREAD_PRIORITY_LOWEST
+ Foreground normal class, THREAD_PRIORITY_HIGHEST
+-3 12 High class, THREAD_PRIORITY_BELOW_NORMAL
+-4 13 High class, THREAD_PRIORITY_NORMAL
+-5 14 High class, THREAD_PRIORITY_ABOVE_NORMAL
+-6 15 Idle, normal, or high class, THREAD_PRIORITY_TIME_CRITICAL
+ High class, THREAD_PRIORITY_HIGHEST
+
+
+ 16 Real-time class, THREAD_PRIORITY_IDLE
+ 22 Real-time class, THREAD_PRIORITY_LOWEST
+ 23 Real-time class, THREAD_PRIORITY_BELOW_NORMAL
+ 24 Real-time class, THREAD_PRIORITY_NORMAL
+ 25 Real-time class, THREAD_PRIORITY_ABOVE_NORMAL
+ 26 Real-time class, THREAD_PRIORITY_HIGHEST
+ 31 Real-time class, THREAD_PRIORITY_TIME_CRITICAL
+****************************************************************************/
+int nice(int niceness) {
+
+ DWORD pclass = IDLE_PRIORITY_CLASS;
+ int priority = THREAD_PRIORITY_NORMAL;
+
+ if (niceness < -6 || niceness > 7) {
+ errno = EPERM;
+ return -1;
+ }
+ switch (niceness) {
+ case 7:
+ pclass = IDLE_PRIORITY_CLASS;
+ priority = THREAD_PRIORITY_LOWEST;
+ break;
+ case 6:
+ pclass = IDLE_PRIORITY_CLASS;
+ priority = THREAD_PRIORITY_BELOW_NORMAL;
+ break;
+ case 5:
+ pclass = IDLE_PRIORITY_CLASS;
+ priority = THREAD_PRIORITY_NORMAL;
+ break;
+ case 4:
+ pclass = IDLE_PRIORITY_CLASS;
+ priority = THREAD_PRIORITY_ABOVE_NORMAL;
+ break;
+ case 3:
+ pclass = IDLE_PRIORITY_CLASS;
+ priority = THREAD_PRIORITY_HIGHEST;
+ break;
+ case 2:
+ pclass = NORMAL_PRIORITY_CLASS;
+ priority = THREAD_PRIORITY_LOWEST;
+ break;
+ case 1:
+ pclass = NORMAL_PRIORITY_CLASS;
+ priority = THREAD_PRIORITY_BELOW_NORMAL;
+ break;
+ case (-1):
+ pclass = NORMAL_PRIORITY_CLASS;
+ priority = THREAD_PRIORITY_ABOVE_NORMAL;
+ break;
+ case (-2):
+ pclass = NORMAL_PRIORITY_CLASS;
+ priority = THREAD_PRIORITY_HIGHEST;
+ break;
+ case (-3):
+ pclass = HIGH_PRIORITY_CLASS;
+ priority = THREAD_PRIORITY_BELOW_NORMAL;
+ break;
+ case (-4):
+ pclass = HIGH_PRIORITY_CLASS;
+ priority = THREAD_PRIORITY_NORMAL;
+ break;
+ case (-5):
+ pclass = HIGH_PRIORITY_CLASS;
+ priority = THREAD_PRIORITY_ABOVE_NORMAL;
+ break;
+ case (-6):
+ pclass = HIGH_PRIORITY_CLASS;
+ priority = THREAD_PRIORITY_HIGHEST;
+ break;
+ default:
+ break;
+ }
+
+ if (!SetPriorityClass(GetCurrentProcess(),pclass)){
+ errno = EPERM;
+ return -1;
+ }
+ if (!SetThreadPriority(GetCurrentThread(),priority)){
+ errno = EPERM;
+ return -1;
+ }
+ return -1;
+}
diff --git a/win32/signal.h b/win32/signal.h
new file mode 100644
index 000000000000..ba7f1b49b7d4
--- /dev/null
+++ b/win32/signal.h
@@ -0,0 +1,125 @@
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+// signal.h: signal emulation things
+// -amol
+//
+#ifndef SIGNAL_H
+#define SIGNAL_H
+
+
+#define NSIG 23
+
+// These must be CTRL_xxx_EVENT+1 (in wincon.h)
+//
+#define SIGINT 1
+#define SIGBREAK 2
+#define SIGHUP 3 //CTRL_CLOSE_EVENT
+// 3 and 4 are reserved. hence we can't use 4 and 5
+#define SIGTERM 6 // ctrl_logoff
+#define SIGKILL 7 // ctrl_shutdown
+
+#define SIGILL 8
+#define SIGFPE 9
+#define SIGALRM 10
+//#define SIGWINCH 11
+#define SIGSEGV 12
+#define SIGSTOP 13
+#define SIGPIPE 14
+#define SIGCHLD 15
+#define SIGCONT 16
+#define SIGTSTP 18
+#define SIGTTOU 19
+#define SIGTTIN 20
+#define SIGABRT 22
+
+#define SIGQUIT SIGBREAK
+
+/* signal action codes */
+
+#define SIG_DFL (void (*)(int))IntToPtr(0) /* default signal action */
+#define SIG_IGN (void (*)(int))IntToPtr(1) /* ignore signal */
+#define SIG_SGE (void (*)(int))IntToPtr(3) /* signal gets error */
+#define SIG_ACK (void (*)(int))IntToPtr(4) /* acknowledge */
+
+
+/* signal error value (returned by signal call on error) */
+
+#define SIG_ERR (void (*)(int))IntToPtr(-1) /* signal error value */
+
+
+#define SIG_BLOCK 0
+#define SIG_UNBLOCK 1
+#define SIG_SETMASK 2
+
+#undef signal
+#define signal _nt_signal
+
+typedef unsigned long sigset_t;
+typedef void Sigfunc (int);
+
+struct sigaction {
+ Sigfunc *sa_handler;
+ sigset_t sa_mask;
+ int sa_flags;
+};
+
+
+#define sigemptyset(ptr) (*(ptr) = 0)
+#define sigfillset(ptr) ( *(ptr) = ~(sigset_t)0,0)
+
+
+/* Function prototypes */
+
+void (* _nt_signal(int, void (*)(int)))(int);
+
+int sigaddset(sigset_t*, int);
+int sigdelset(sigset_t*,int);
+unsigned int alarm(unsigned int);
+
+int sigismember(const sigset_t *set, int);
+int sigprocmask(int ,const sigset_t*,sigset_t*);
+int sigaction(int, const struct sigaction *, struct sigaction*);
+int sigsuspend(const sigset_t *sigmask);
+
+#define WNOHANG 0
+#define WUNTRACED 1
+
+#define WIFEXITED(a) 1
+#define WEXITSTATUS(a) (a)
+//#define WIFSIGNALED(a) ((a!= -1)&&(((((unsigned long)(a)) >>24) & 0xC0)!=0))
+#define WIFSIGNALED(a) ((a !=-1)&&((((unsigned long)(a)) & 0xC0000000 ) != 0))
+#define WTERMSIG(a) (((unsigned long)(a))==0xC000013AL?SIGINT:SIGSEGV)
+#define WCOREDUMP(a) 0
+#define WIFSTOPPED(a) 0
+#define WSTOPSIG(a) 0
+
+int waitpid(pid_t, int*,int);
+int times(struct tms*);
+
+#endif SIGNAL_H
diff --git a/win32/stdio.c b/win32/stdio.c
new file mode 100644
index 000000000000..2fa3fc66869a
--- /dev/null
+++ b/win32/stdio.c
@@ -0,0 +1,628 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/stdio.c,v 1.10 2010/05/27 04:00:23 amold Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * stdio.c Implement a whole load of i/o functions.
+ * This makes it much easier to keep track of inherited handles and
+ * also makes us reasonably vendor crt-independent.
+ * -amol
+ *
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#define STDIO_C
+#include <ntport.h>
+#include <forkdata.h>
+
+
+#define __MAX_OPEN_FILES 64
+
+#define FIOCLEX 1
+#define FCONSOLE 2
+
+typedef struct _myfile {
+ HANDLE handle;
+ unsigned long flags;
+} MY_FILE;
+
+typedef unsigned long u_long;
+
+#define INVHL (INVALID_HANDLE_VALUE)
+
+MY_FILE __gOpenFiles[__MAX_OPEN_FILES]={0};
+MY_FILE __gOpenFilesCopy[__MAX_OPEN_FILES]={0};
+
+MY_FILE *my_stdin=0, *my_stdout=0, *my_stderr=0;
+
+extern int didfds;
+int __dup_stdin = 0;
+
+
+void init_stdio(void) {
+
+ int i;
+ __gOpenFiles[0].handle = GetStdHandle(STD_INPUT_HANDLE);
+ __gOpenFiles[1].handle = GetStdHandle(STD_OUTPUT_HANDLE);
+ __gOpenFiles[2].handle = GetStdHandle(STD_ERROR_HANDLE);
+
+ __gOpenFiles[0].flags = (GetFileType(ULongToPtr(STD_INPUT_HANDLE))==
+ FILE_TYPE_CHAR)? FCONSOLE:0;
+ __gOpenFiles[1].flags = (GetFileType(ULongToPtr(STD_OUTPUT_HANDLE))==
+ FILE_TYPE_CHAR)? FCONSOLE:0;
+ __gOpenFiles[2].flags = (GetFileType(ULongToPtr(STD_ERROR_HANDLE))==
+ FILE_TYPE_CHAR)? FCONSOLE:0;
+
+ for(i=3;i<__MAX_OPEN_FILES;i++) {
+ __gOpenFiles[i].handle = INVHL;
+ __gOpenFilesCopy[i].handle = INVHL;
+ __gOpenFiles[i].flags = 0;
+ }
+
+ my_stdin = &__gOpenFiles[0];
+ my_stdout = &__gOpenFiles[1];
+ my_stderr = &__gOpenFiles[2];
+}
+
+ void nt_close_on_exec(int fd, int on) {
+ if(on)
+ __gOpenFiles[fd].flags |= FIOCLEX;
+ else
+ __gOpenFiles[fd].flags &= ~FIOCLEX;
+ }
+void restore_fds(void ) {
+ int i;
+ int min=3;
+
+ if (__forked && (didfds|| __dup_stdin))
+ min =0;
+ //
+ // ok for tcsh. see fork.c for why
+ //
+ __gOpenFiles[0].handle = INVHL;
+ __gOpenFiles[1].handle = INVHL;
+ __gOpenFiles[2].handle = INVHL;
+ my_stdin = &__gOpenFiles[0];
+ my_stdout = &__gOpenFiles[1];
+ my_stderr = &__gOpenFiles[2];
+ for(i=min;i<__MAX_OPEN_FILES;i++) {
+ if (__gOpenFilesCopy[i].handle == INVHL)
+ continue;
+ __gOpenFiles[i].handle = __gOpenFilesCopy[i].handle ;
+ __gOpenFiles[i].flags = __gOpenFilesCopy[i].flags ;
+ }
+}
+void close_copied_fds(void ) {
+ int i;
+ int min=3;
+ if (didfds|| __dup_stdin)
+ min =0;
+ for(i=min;i<__MAX_OPEN_FILES;i++) {
+ if (__gOpenFilesCopy[i].handle == INVHL)
+ continue;
+ CloseHandle((HANDLE)__gOpenFilesCopy[i].handle);
+ __gOpenFilesCopy[i].handle = INVHL;
+ }
+ __dup_stdin=0;
+}
+void copy_fds(void ) {
+ int i;
+ int min=3;
+ if (didfds || __dup_stdin)
+ min =0;
+ for(i=min;i<__MAX_OPEN_FILES;i++) {
+ if (__gOpenFiles[i].handle == INVHL) {
+ __gOpenFilesCopy[i].handle = INVHL;
+ continue;
+ }
+
+ if(!DuplicateHandle(GetCurrentProcess(),
+ (HANDLE)__gOpenFiles[i].handle ,
+ GetCurrentProcess(),
+ (HANDLE*)&__gOpenFilesCopy[i].handle,
+ 0, TRUE, DUPLICATE_SAME_ACCESS) )
+ __gOpenFilesCopy[i].handle = INVHL;
+ __gOpenFilesCopy[i].flags = __gOpenFiles[i].flags;
+ }
+}
+intptr_t __nt_get_osfhandle(int fd) {
+ return (intptr_t)(__gOpenFiles[fd].handle);
+}
+int __nt_open_osfhandle(intptr_t h1, int mode) {
+ int i;
+
+ UNREFERENCED_PARAMETER(mode);
+
+ for(i=0;i<__MAX_OPEN_FILES;i++) {
+ if (__gOpenFiles[i].handle == INVHL) {
+ __gOpenFiles[i].handle = (HANDLE)h1;
+ __gOpenFiles[i].flags = 0;
+ return i;
+ }
+ }
+ errno = EMFILE;
+ return -1;
+}
+int nt_close(int fd) {
+
+ if( (fd == -1) ||(__gOpenFiles[fd].handle == INVHL))
+ return 0;
+ CloseHandle((HANDLE)(__gOpenFiles[fd].handle));
+ __gOpenFiles[fd].handle = INVHL;
+ __gOpenFiles[fd].flags = 0;
+
+ // dprintf("closing 0x%08x\n",(__gOpenFiles[fd].handle));
+ return 0;
+}
+int nt_access(char *filename, int mode) {
+
+ DWORD attribs=(DWORD)-1, bintype;
+ int tries=0;
+ char buf[512];/*FIXBUF*/
+
+ if (!filename) {
+ errno = ENOENT;
+ return -1;
+ }
+ (void)StringCbPrintf(buf,sizeof(buf),"%s",filename);
+retry:
+ attribs = GetFileAttributes(buf);
+ tries++;
+
+ if (attribs == (DWORD) -1) {
+ if( (GetLastError() == ERROR_FILE_NOT_FOUND) && (mode & X_OK) ) {
+ switch(tries){
+ case 1:
+ (void)StringCbPrintf(buf,sizeof(buf),"%s.exe",filename);
+ break;
+ case 2:
+ (void)StringCbPrintf(buf,sizeof(buf),"%s.cmd",filename);
+ break;
+ case 3:
+ (void)StringCbPrintf(buf,sizeof(buf),"%s.bat",filename);
+ break;
+ case 4:
+ (void)StringCbPrintf(buf,sizeof(buf),"%s.com",filename);
+ break;
+ default:
+ goto giveup;
+ break;
+ }
+ goto retry;
+ }
+ }
+giveup:
+ if (attribs == (DWORD)-1 ) {
+ errno = EACCES;
+ return -1;
+ }
+ if ( (mode & W_OK) && (attribs & FILE_ATTRIBUTE_READONLY) ) {
+ errno = EACCES;
+ return -1;
+ }
+ if (mode & X_OK) {
+ if ((mode & XD_OK) && (attribs & FILE_ATTRIBUTE_DIRECTORY) ){
+ errno = EACCES;
+ return -1;
+ }
+ if ((!(attribs & FILE_ATTRIBUTE_DIRECTORY)) &&
+ !GetBinaryType(buf,&bintype) &&(tries >4) ) {
+ errno = EACCES;
+ return -1;
+ }
+ }
+ return 0;
+}
+int nt_seek(HANDLE h1, long offset, int how) {
+ DWORD dwmove;
+
+ switch(how) {
+ case SEEK_CUR:
+ dwmove = FILE_CURRENT;
+ break;
+ case SEEK_END:
+ dwmove = FILE_END;
+ break;
+ case SEEK_SET:
+ dwmove = FILE_BEGIN;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (SetFilePointer(h1,offset,NULL,dwmove) == -1){
+ errno = EBADF;
+ return -1;
+ }
+ return 0;
+}
+int nt_lseek(int fd,long offset, int how) {
+ HANDLE h1 ;
+ h1 =__gOpenFiles[fd].handle;
+ return nt_seek(h1,offset,how);
+}
+int nt_isatty(int fd) {
+ return (__gOpenFiles[fd].flags & FCONSOLE);
+}
+int nt_dup(int fdin) {
+
+ HANDLE hdup;
+ HANDLE horig = __gOpenFiles[fdin].handle;
+ int ret;
+
+
+ if (!DuplicateHandle(GetCurrentProcess(),
+ horig,
+ GetCurrentProcess(),
+ &hdup,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS)) {
+ errno = GetLastError();
+ errno = EBADF;
+ return -1;
+ }
+ ret = __nt_open_osfhandle((intptr_t)hdup,_O_BINARY | _O_NOINHERIT);
+
+ __gOpenFiles[ret].flags = __gOpenFiles[fdin].flags;
+
+ return ret;
+}
+int nt_dup2(int fdorig,int fdcopy) {
+
+ HANDLE hdup;
+ HANDLE horig = __gOpenFiles[fdorig].handle;
+
+
+ if (__gOpenFiles[fdcopy].handle != INVHL) {
+ CloseHandle((HANDLE)__gOpenFiles[fdcopy].handle );
+ __gOpenFiles[fdcopy].handle = INVHL;
+ __gOpenFiles[fdcopy].flags = 0;
+ }
+ if (!DuplicateHandle(GetCurrentProcess(),
+ horig,
+ GetCurrentProcess(),
+ &hdup,
+ 0,
+ fdcopy<3?TRUE:FALSE, DUPLICATE_SAME_ACCESS)) {
+ errno = GetLastError();
+ errno = EBADF;
+ return -1;
+ }
+ __gOpenFiles[fdcopy].handle = hdup;
+ __gOpenFiles[fdcopy].flags = __gOpenFiles[fdorig].flags;
+ switch(fdcopy) {
+ case 0:
+ SetStdHandle(STD_INPUT_HANDLE,hdup);
+ break;
+ case 1:
+ SetStdHandle(STD_OUTPUT_HANDLE,hdup);
+ break;
+ case 2:
+ SetStdHandle(STD_ERROR_HANDLE,hdup);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+int nt_pipe2(HANDLE hpipe[2]) {
+
+ SECURITY_ATTRIBUTES secd;
+
+ secd.nLength=sizeof(secd);
+ secd.lpSecurityDescriptor=NULL;
+ secd.bInheritHandle=FALSE;
+
+ return (!CreatePipe(&hpipe[0],&hpipe[1],&secd,0));
+}
+int nt_pipe(int hpipe[2]) {
+ HANDLE hpipe2[2];
+
+ nt_pipe2(hpipe2);
+ hpipe[0] = __nt_open_osfhandle((intptr_t)hpipe2[0],O_NOINHERIT);
+ hpipe[1] = __nt_open_osfhandle((intptr_t)hpipe2[1],O_NOINHERIT);
+ return 0;
+}
+/* check if name is //server. if checkifShare is set,
+ * also check if //server/share
+ */
+int is_server(const char *name,int checkifShare) {
+ const char *p1, *p2;
+
+ if (!*name || !*(name+1))
+ return 0;
+
+ p1 = name;
+ if (((p1[0] != '/') && (p1[0] != '\\') ) ||
+ ((p1[1] != '/') && (p1[1] != '\\') ))
+ return 0;
+
+ p2 = p1 + 2;
+ while (*p2 && *p2 != '/' && *p2 != '\\')
+#ifdef DSPMBYTE
+ if (Ismbyte1(*p2) && *(p2 + 1))
+ p2 += 2;
+ else
+#endif /* DSPMBYTE */
+ p2++;
+
+ /* just check for server */
+ if (!checkifShare) {
+ /* null terminated unc server name */
+ /* terminating '/' (//server/) is also ok */
+ if (!*p2 || !*(p2+1))
+ return 1;
+
+ }
+ else {
+ if (!*p2 || !*(p2+1))
+ return 0;
+ p2++;
+ while(*p2 && *p2 != '/' && *p2 != '\\')
+ p2++;
+ if (!*p2 || !*(p2+1))
+ return 1;
+ }
+ return 0;
+
+}
+__inline int is_unc(char *filename) {
+ if (*filename && (*filename == '/' || *filename == '\\')
+ && *(filename+1)
+ && (*(filename+1) == '/' || *(filename+1) == '\\')) {
+ return 1;
+ }
+ return 0;
+}
+int nt_stat(const char *filename, struct stat *stbuf) {
+
+ // stat hangs on server name
+ // Use any directory, since the info in stat means %$!* on
+ // windows anyway.
+ // -amol 5/28/97
+ /* is server or share */
+ if (is_server(filename,0) || is_server(filename,1) ||
+ (*(filename+1) && *(filename+1) == ':' && !*(filename+2)) ) {
+ return _stat("C:/",(struct _stat *)stbuf);
+ }
+ else {
+ char *last = (char*)filename + strlen(filename) -1;
+ int rc = 0;
+ BOOL lastslash = (*last == '/');
+ if(lastslash)
+ {
+ *last = 0;
+ }
+ rc = _stat(filename,(struct _stat *)stbuf);
+ if(lastslash)
+ {
+ *last = '/';
+ }
+ return rc;
+ }
+}
+//
+// replacement for creat that makes handle non-inheritable.
+// -amol
+//
+int nt_creat(const char *filename, int mode) {
+ // ignore the bloody mode
+
+ int fd = 0,is_cons =0;
+ HANDLE retval;
+ SECURITY_ATTRIBUTES security;
+
+ UNREFERENCED_PARAMETER(mode);
+
+
+ security.nLength = sizeof(security);
+ security.lpSecurityDescriptor = NULL;
+ security.bInheritHandle = FALSE;
+
+ if (!_stricmp(filename,"/dev/tty") ){
+ filename = "CONOUT$";
+ is_cons = 1;
+ }
+ else if (!_stricmp(filename,"/dev/null") ){
+ filename = "NUL";
+ }
+ else if (!_stricmp(filename,"/dev/clipboard")) {
+ retval = create_clip_writer_thread();
+ if (retval == INVHL)
+ return -1;
+ goto get_fd;
+ }
+ retval = CreateFile(filename,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ is_cons?NULL:&security,
+ CREATE_ALWAYS,
+ 0,
+ NULL);
+
+ if (retval == INVALID_HANDLE_VALUE) {
+ errno = EACCES;
+ return -1;
+ }
+get_fd:
+ fd = __nt_open_osfhandle((intptr_t)retval,_O_BINARY);
+ if (fd <0) {
+ //should never happen
+ abort();
+ }
+ else {
+ if (is_cons) {
+ __gOpenFiles[fd].flags = FCONSOLE;
+ }
+ }
+ return fd;
+
+}
+int nt_open(const char *filename, int perms,...) {
+
+ // ignore the bloody mode
+
+ int fd,mode, is_cons=0;
+ HANDLE retval;
+ SECURITY_ATTRIBUTES security;
+ DWORD dwAccess, dwFlags, dwCreateDist;
+ va_list ap;
+
+ va_start(ap,perms);
+ mode = va_arg(ap,int);
+ va_end(ap);
+
+ if (!lstrcmp(filename,"/dev/tty") ){
+ if (perms == O_RDONLY) //o_rdonly is 0
+ filename = "CONIN$";
+ else if (perms & O_WRONLY)
+ filename = "CONOUT$";
+ is_cons = 1;
+ }
+ else if (!lstrcmp(filename,"/dev/null") ){
+ filename = "NUL";
+ }
+ else if (!_stricmp(filename,"/dev/clipboard")) {
+ retval = create_clip_reader_thread();
+ goto get_fd;
+ }
+ security.nLength = sizeof(security);
+ security.lpSecurityDescriptor = NULL;
+ security.bInheritHandle = FALSE;
+
+ switch (perms & (_O_RDONLY | _O_WRONLY | _O_RDWR) ) {
+ case _O_RDONLY:
+ dwAccess = GENERIC_READ;
+ break;
+ case _O_WRONLY:
+ dwAccess = GENERIC_WRITE;
+ break;
+ case _O_RDWR:
+ dwAccess = GENERIC_READ | GENERIC_WRITE ;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ switch (perms & (_O_CREAT | _O_TRUNC) ){
+ case 0:
+ dwCreateDist = OPEN_EXISTING;
+ break;
+ case _O_CREAT:
+ dwCreateDist = CREATE_ALWAYS;
+ break;
+ case _O_CREAT | _O_TRUNC:
+ dwCreateDist = CREATE_ALWAYS;
+ break;
+ case _O_TRUNC:
+ dwCreateDist = TRUNCATE_EXISTING;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ dwFlags = 0;
+ if (perms & O_TEMPORARY)
+ dwFlags = FILE_FLAG_DELETE_ON_CLOSE;
+ retval = CreateFile(filename,
+ dwAccess,//GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ &security,
+ dwCreateDist,//CREATE_ALWAYS,
+ dwFlags,
+ NULL);
+
+ if (retval == INVALID_HANDLE_VALUE) {
+ int err = GetLastError();
+ if (err == ERROR_FILE_NOT_FOUND)
+ errno = ENOENT;
+ else
+ errno = EACCES;
+ return -1;
+ }
+ if (perms & O_APPEND) {
+ SetFilePointer(retval,0,NULL,FILE_END);
+ }
+get_fd:
+ fd = __nt_open_osfhandle((intptr_t)retval,_O_BINARY);
+ if (fd <0) {
+ //should never happen
+ abort();
+ }
+ else {
+ if (is_cons) {
+ __gOpenFiles[fd].flags = FCONSOLE;
+ }
+ }
+ return fd;
+
+}
+/*
+ * This should be the LAST FUNCTION IN THIS FILE
+ *
+ */
+#undef fstat
+#undef _open_osfhandle
+#undef close
+int nt_fstat(int fd, struct stat *stbuf) {
+ int realfd;
+ HANDLE h1;
+
+ errno = EBADF;
+
+ if(!DuplicateHandle(GetCurrentProcess(),
+ (HANDLE)__gOpenFiles[fd].handle,
+ GetCurrentProcess(),
+ &h1,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS) )
+ return -1;
+ realfd = _open_osfhandle((intptr_t)h1,0);
+ if (realfd <0 )
+ return -1;
+
+ if( fstat(realfd,stbuf) <0 ) {
+ _close(realfd);
+ return -1;
+ }
+ _close(realfd);
+ errno =0;
+ return 0;
+
+}
+
diff --git a/win32/support.c b/win32/support.c
new file mode 100644
index 000000000000..dd3c117af693
--- /dev/null
+++ b/win32/support.c
@@ -0,0 +1,941 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/support.c,v 1.14 2008/08/31 14:09:01 amold Exp $*/
+/*-
+ * Copyright (c) 1980, 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * support.c
+ * various routines to do exec, etc.
+ *
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <wincon.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <locale.h>
+#include "ntport.h"
+#include "sh.err.h"
+#include "sh.h"
+#include "nt.const.h"
+
+
+DWORD gdwPlatform,gdwVersion;
+unsigned short __nt_really_exec = 0,__nt_child_nohupped =0;
+DWORD gdwStackSize = 524288;//0.5 MB
+
+void path_slashify(char *pstr) {
+ while(*pstr) {
+#ifdef DSPMBYTE
+ if (Ismbyte1(*pstr) && *(pstr + 1))
+ pstr ++;
+ else
+#endif /* DSPMBYTE */
+ if (*pstr == '\\')
+ *pstr = '/';
+ pstr++;
+ }
+}
+
+void do_nothing(const wchar_t *p1, const wchar_t *p2, const wchar_t*p3,
+ unsigned int p4, uintptr_t p5) {
+ UNREFERENCED_PARAMETER(p1);
+ UNREFERENCED_PARAMETER(p2);
+ UNREFERENCED_PARAMETER(p3);
+ UNREFERENCED_PARAMETER(p4);
+ UNREFERENCED_PARAMETER(p5);
+}
+void nt_init(void) {
+
+
+#ifdef SECURE_CD
+ {
+ char temp[512];/*FIXBUF*/
+ extern char gcurr_drive;
+ if(!GetCurrentDirectory(512,temp))
+ ExitProcess((DWORD)-1);
+ gcurr_drive=temp[0];
+ }
+#endif SECURE_CD
+
+ _set_invalid_parameter_handler(do_nothing);
+ init_stdio();
+ nt_init_signals();
+ nt_term_init();
+ init_hb_subst();
+ setlocale(LC_ALL,"");
+ init_shell_dll();
+ init_plister();
+ fork_init();
+ init_clipboard();
+ return;
+}
+void nt_cleanup(void){
+ nt_term_cleanup();
+ nt_cleanup_signals();
+ cleanup_netbios();
+}
+void caseify_pwd(char *curwd) {
+ char *sp, *dp, p,*s;
+ WIN32_FIND_DATA fdata;
+ HANDLE hFind;
+
+ if (gdwPlatform !=VER_PLATFORM_WIN32_NT)
+ return;
+
+ if (*curwd == '\\' && (!curwd[1] || curwd[1] == '\\'))
+ return;
+ sp = curwd +3;
+ dp = curwd +3;
+ do {
+ p= *sp;
+ if (p && p != '\\'){
+ sp++;
+ continue;
+ }
+ else {
+ *sp = 0;
+ hFind = FindFirstFile(curwd,&fdata);
+ *sp = p;
+ if (hFind != INVALID_HANDLE_VALUE) {
+ FindClose(hFind);
+ s = fdata.cFileName;
+ while(*s) {
+ *dp++ = *s++;
+ }
+ dp++;
+ sp = dp;
+ }
+ else {
+ sp++;
+ dp = sp;
+ }
+ }
+ sp++;
+ }while(p != 0);
+
+}
+static char defcwd[MAX_PATH];
+char * forward_slash_get_cwd(char * path, size_t maxlen) {
+
+ char *ptemp;
+ Char *vp;
+ int rc ;
+
+ if ((path == NULL) || (maxlen == 0)) {
+ path = &defcwd[0];
+ maxlen = MAX_PATH;
+ }
+
+ rc = GetCurrentDirectory((DWORD)maxlen,path);
+ if (rc > maxlen) {
+ errno = ERANGE;
+ return NULL;
+ }
+ vp = varval(STRNTcaseifypwd);
+ if (vp != STRNULL) {
+ caseify_pwd(path);
+ }
+ ptemp=path;
+
+ path_slashify(ptemp);
+
+ return path;
+}
+void getmachine (void) {
+
+ char temp[256];
+ char *vendor, *ostype;
+ OSVERSIONINFO osver;
+ SYSTEM_INFO sysinfo;
+
+
+ memset(&osver,0,sizeof(osver));
+ memset(&sysinfo,0,sizeof(sysinfo));
+ vendor = "Microsoft";
+
+ tsetenv(STRVENDOR,str2short(vendor));
+
+ osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+ if (!GetVersionEx(&osver)) {
+ MessageBox(NULL,"GetVersionEx failed in getmachine",
+ "tcsh",MB_ICONHAND);
+ ExitProcess(0xFF);
+ }
+ GetSystemInfo(&sysinfo);
+
+ if(osver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+ char *ostr;
+ ostype = "WindowsNT";
+ ostr = "Windows NT";
+
+ (void)StringCbPrintf(temp,sizeof(temp),"%s %d.%d Build %d (%s)",
+ ostr,
+ osver.dwMajorVersion,osver.dwMinorVersion,
+ osver.dwBuildNumber,
+ osver.szCSDVersion[0]?osver.szCSDVersion:"");
+ tsetenv(STRHOSTTYPE,str2short(temp));
+ }
+ else if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
+ ostype = "Windows9x";
+ (void)StringCbPrintf(temp,sizeof(temp),
+ "Win9x %d.%d:%d",osver.dwMajorVersion,osver.dwMinorVersion,
+ LOWORD(osver.dwBuildNumber));
+ tsetenv(STRHOSTTYPE,str2short(temp));
+ }
+ else {
+ ostype = "WindowsWhoKnows";
+ MessageBox(NULL,"Unknown platform","tcsh",MB_ICONHAND);
+ }
+ tsetenv(STROSTYPE,str2short(ostype));
+ switch (sysinfo.wProcessorArchitecture) {
+ case PROCESSOR_ARCHITECTURE_INTEL:
+ if ( ( sysinfo.wProcessorLevel < 3) ||
+ ( sysinfo.wProcessorLevel > 9) )
+ sysinfo.wProcessorLevel = 3;
+
+ (void)StringCbPrintf(temp,sizeof(temp),
+ "i%d86",sysinfo.wProcessorLevel);
+ break;
+ case PROCESSOR_ARCHITECTURE_ALPHA:
+ (void)StringCbPrintf(temp,sizeof(temp),"Alpha");
+ break;
+ case PROCESSOR_ARCHITECTURE_MIPS:
+ (void)StringCbPrintf(temp,sizeof(temp),"Mips");
+ break;
+ case PROCESSOR_ARCHITECTURE_PPC:
+ (void)StringCbPrintf(temp,sizeof(temp),"PPC");
+ break;
+ case PROCESSOR_ARCHITECTURE_AMD64:
+ (void)StringCbPrintf(temp,sizeof(temp),"AMD64");
+ break;
+ default:
+ (void)StringCbPrintf(temp,sizeof(temp),"Unknown");
+ break;
+ }
+ tsetenv(STRMACHTYPE,str2short(temp));
+
+}
+void nt_exec(char *prog, char**args) {
+ nt_execve(prog,args,NULL);
+}
+void nt_execve(char *prog, char**args, char**envir ) {
+
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ HANDLE htemp;
+ BOOL bRet;
+ DWORD type=0;
+ DWORD dwCreationflags;
+ unsigned int priority;
+ char *argv0= NULL;
+ char *cmdstr, *cmdend ;
+ char *originalPtr;
+ unsigned int cmdsize,cmdlen;
+ char *p2;
+ char **savedargs;
+ int retries=0;
+ int hasdot =0;
+ int is_winnt ;
+
+ UNREFERENCED_PARAMETER(envir);
+
+ memset(&si,0,sizeof(si));
+ savedargs = args;
+
+ /*
+ * This memory is not freed because we are exec()ed and will
+ * not be alive long.
+ */
+ originalPtr = cmdstr= heap_alloc(MAX_PATH<<2);
+
+ is_winnt = (gdwPlatform != VER_PLATFORM_WIN32_WINDOWS);
+
+
+ cmdsize = MAX_PATH<<2;
+
+ p2 = cmdstr;
+
+ cmdlen = 0;
+ cmdlen += copy_quote_and_fix_slashes(prog,cmdstr,&hasdot);
+
+ p2 += cmdlen;
+
+ /* If the command was not quoted ,
+ skip initial character we left for quote */
+ if (*cmdstr != '"') {
+ *cmdstr = 'A';
+ cmdstr++;
+ cmdsize--;
+ }
+ *p2 = 0;
+ cmdend = p2;
+
+
+ if (!is_winnt){
+ argv0 = NULL;
+ goto win95_directly_here;
+ }
+ else {
+ argv0 = heap_alloc(MAX_PATH); /* not freed */
+ (void)StringCbPrintf(argv0,MAX_PATH,"%s",prog);
+ }
+
+retry:
+
+ bRet=GetBinaryType(argv0,&type);
+ dprintf("binary type for %s is %d\n",argv0,bRet);
+ //
+ // For NT, append .EXE and retry
+ //
+ if (is_winnt && !bRet ) {
+ /* Don't append .EXE if it could be a script file */
+ if (GetLastError() == ERROR_BAD_EXE_FORMAT){
+ errno = ENOEXEC;
+ if (!__nt_only_start_exes)
+ try_shell_ex(args,1,FALSE); //can't throw on error
+ return;
+ }
+ else if ( retries ){
+ if (
+ ( (argv0[0] == '\\') ||(argv0[0] == '/') ) &&
+ ( (argv0[1] == '\\') ||(argv0[1] == '/') ) &&
+ (!args[1])
+ )
+ if (!__nt_only_start_exes)
+ try_shell_ex(args,1,FALSE);
+ errno = ENOENT;
+ }
+ if (retries > 1){
+ return;
+ }
+ // Try uppercase once and then lower case
+ //
+ if (!retries) {
+ (void)StringCbPrintf(argv0,MAX_PATH,"%s.exe",prog);
+ }
+ else {
+ (void)StringCbPrintf(argv0,MAX_PATH,"%s.EXE",prog);
+ /* fix for clearcase */
+ }
+ retries++;
+ goto retry;
+ }
+
+win95_directly_here:
+
+ si.cb = sizeof(STARTUPINFO);
+ si.dwFlags = STARTF_USESTDHANDLES;
+ htemp= (HANDLE)_get_osfhandle(0);
+ DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(),
+ &si.hStdInput,0,TRUE,DUPLICATE_SAME_ACCESS);
+ htemp= (HANDLE)_get_osfhandle(1);
+ DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(),
+ &si.hStdOutput,0,TRUE,DUPLICATE_SAME_ACCESS);
+ htemp= (HANDLE)_get_osfhandle(2);
+ DuplicateHandle(GetCurrentProcess(),htemp,GetCurrentProcess(),
+ &si.hStdError,0,TRUE,DUPLICATE_SAME_ACCESS);
+
+
+
+ args++; // the first arg is the command
+
+
+ dprintf("nt_execve calling c_a_a_q");
+ if(!concat_args_and_quote(args,&originalPtr,&cmdstr,&cmdlen,&cmdend,
+ &cmdsize))
+ {
+ dprintf("concat_args_and_quote failed\n");
+ heap_free(originalPtr);
+ errno = ENOMEM;
+ goto fail_return;
+ }
+
+ *cmdend = 0;
+
+ dwCreationflags = GetPriorityClass(GetCurrentProcess());
+ if (__nt_child_nohupped) {
+ dwCreationflags |= DETACHED_PROCESS;
+ }
+ priority = GetThreadPriority(GetCurrentThread());
+
+ (void)fix_path_for_child();
+
+ if (is_winnt)
+ dwCreationflags |= CREATE_SUSPENDED;
+
+
+re_cp:
+ dprintf("argv0 %s cmdstr %s\n",argv0,cmdstr);
+ bRet = CreateProcessA(argv0, cmdstr,
+ NULL, NULL,
+ TRUE, // need this for redirecting std handles
+ dwCreationflags,
+ NULL, NULL,
+ &si,
+ &pi);
+ if (!bRet){
+ if (GetLastError() == ERROR_BAD_EXE_FORMAT) {
+ if (!__nt_only_start_exes)
+ try_shell_ex(savedargs,1,FALSE);
+ errno = ENOEXEC;
+ }
+ else if (GetLastError() == ERROR_INVALID_PARAMETER) {
+ /* can't get invalid parameter, so this must be
+ * the case when we exceed the command length limit.
+ */
+ errno = ENAMETOOLONG;
+ }
+ else {
+ errno = ENOENT;
+ }
+ if (!is_winnt && !hasdot) { //append '.' to the end if needed
+ (void)StringCbCat(cmdstr,cmdsize,".");
+ hasdot=1;
+ goto re_cp;
+ }
+ }
+ else{
+ int gui_app ;
+ char guivar[50];
+
+ if (GetEnvironmentVariable("TCSH_NOASYNCGUI",guivar,50))
+ gui_app=0;
+ else {
+ if (is_winnt || hasdot)
+ gui_app= is_gui(argv0);
+ else
+ gui_app = is_9x_gui(prog);
+ }
+
+ if (is_winnt && !SetThreadPriority(pi.hThread,priority) ) {
+ priority =GetLastError();
+ }
+ if (is_winnt)
+ ResumeThread(pi.hThread);
+ errno= 0;
+
+ if (__nt_really_exec||__nt_child_nohupped || gui_app){
+ ExitProcess(0);
+ }
+ else {
+ DWORD exitcode=0;
+ WaitForSingleObject(pi.hProcess,INFINITE);
+ (void)GetExitCodeProcess(pi.hProcess,&exitcode);
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ /*
+ * If output was redirected to /dev/clipboard,
+ * we need to close the pipe handles
+ */
+ if (is_dev_clipboard_active) {
+ CloseHandle((HANDLE)_get_osfhandle(0));
+ CloseHandle((HANDLE)_get_osfhandle(1));
+ CloseHandle((HANDLE)_get_osfhandle(2));
+ CloseHandle(si.hStdInput);
+ CloseHandle(si.hStdOutput);
+ CloseHandle(si.hStdError);
+ WaitForSingleObject(ghdevclipthread,60*1000);
+ }
+ ExitProcess(exitcode);
+ }
+ }
+fail_return:
+ CloseHandle(si.hStdInput);
+ CloseHandle(si.hStdOutput);
+ CloseHandle(si.hStdError);
+ return;
+}
+/* This function from Mark Tucker (mtucker@fiji.sidefx.com) */
+int quoteProtect(char *dest, char *src,unsigned long destsize) {
+ char *prev, *curr;
+ for (curr = src; *curr; curr++) {
+
+ // Protect " from MS-DOS expansion
+ if (*curr == '"') {
+ // Now, protect each preceeding backslash
+ for (prev = curr-1; prev >= src && *prev == '\\'; prev--) {
+ *dest++ = '\\';
+ destsize--;
+ if(destsize == 0)
+ return ERROR_BUFFER_OVERFLOW;
+ }
+
+ *dest++ = '\\';
+ destsize--;
+ if(destsize == 0)
+ return ERROR_BUFFER_OVERFLOW;
+ }
+ *dest++ = *curr;
+ destsize--;
+ if(destsize == 0)
+ return ERROR_BUFFER_OVERFLOW;
+
+ }
+ *dest = 0;
+
+ return NO_ERROR;
+}
+
+
+int gethostname(char *buf, int len) {
+ GetComputerName(buf,(DWORD*)&len);
+ return 0;
+}
+int nt_chdir (char *path) {
+ char *tmp = path;
+ if (gdwPlatform !=VER_PLATFORM_WIN32_NT) {
+ while(*tmp) {
+ if (*tmp == '/') *tmp = '\\';
+ tmp++;
+ }
+ }
+ return _chdir(path);
+}
+void WINAPI uhef( EXCEPTION_POINTERS *lpep) {
+ ExitProcess(lpep->ExceptionRecord->ExceptionCode);
+}
+extern BOOL CreateWow64Events(DWORD,HANDLE*,HANDLE*,BOOL);
+// load kernel32 and look for iswow64. if not found, assume FALSE
+BOOL bIsWow64Process = FALSE;
+void init_wow64(void) {
+ HMODULE hlib;
+ //BOOL (WINAPI *pfnIsWow64)(HANDLE,BOOL*);
+ FARPROC pfnIsWow64;
+
+ bIsWow64Process = FALSE;
+
+ hlib = LoadLibrary("kernel32.dll");
+ if (!hlib) {
+ return;
+ }
+ pfnIsWow64 = GetProcAddress(hlib,"IsWow64Process");
+ if (!pfnIsWow64) {
+ FreeLibrary(hlib);
+ return;
+ }
+ if (!pfnIsWow64(GetCurrentProcess(),&bIsWow64Process) )
+ bIsWow64Process = FALSE;
+
+ FreeLibrary(hlib);
+ return;
+
+}
+
+extern void mainCRTStartup(void *);
+
+/*
+ * heap_init() MUST NOT be moved outside the entry point. Sometimes child
+ * processes may load random DLLs not loaded by the parent and
+ * use the heap address reserved for fmalloc() in the parent. This
+ * causes havoc as no dynamic memory can then be inherited.
+ *
+ */
+extern void heap_init(void);
+
+#include <forkdata.h>
+void silly_entry(void *peb) {
+ char * path1=NULL;
+ int rc;
+ char temp[MAX_PATH+5];
+ char buf[MAX_PATH];
+ char ptr1[MAX_PATH];
+ char ptr2[MAX_PATH];
+ char ptr3[MAX_PATH];
+ OSVERSIONINFO osver;
+
+ osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+
+ if (!GetVersionEx(&osver)) {
+ MessageBox(NULL,"GetVersionEx failed","tcsh",MB_ICONHAND);
+ ExitProcess(0xFF);
+ }
+ gdwVersion = osver.dwMajorVersion;
+
+ if(gdwVersion < 6) // no wow64 hackery for vista.
+ {
+ init_wow64();
+ }
+
+#ifdef _M_IX86
+ // look at the explanation in fork.c for why we do these steps.
+ if (bIsWow64Process) {
+ HANDLE h64Parent,h64Child;
+ char *stk, *end;
+ DWORD mb = (1<<20);
+
+ // if we found the events, then we're the product of a fork()
+ if (CreateWow64Events(GetCurrentProcessId(),
+ &h64Parent,&h64Child,TRUE)) {
+
+ if (!h64Parent || !h64Child)
+ return;
+
+ // tell parent we're rolling
+ SetEvent(h64Child);
+
+ if(WaitForSingleObject(h64Parent,FORK_TIMEOUT) != WAIT_OBJECT_0) {
+ return;
+ }
+
+ // if __forked is 0, we shouldn't have found the events
+ if (!__forked)
+ return;
+ }
+
+ // now create the stack
+
+ if (!__forked) {
+ stk = VirtualAlloc(NULL,mb+65536,MEM_COMMIT,PAGE_READWRITE);
+ if (!stk) {
+ dprintf("virtual alloc in parent failed %d\n",GetLastError());
+ return;
+ }
+ end = stk + mb + 65536;
+ end -= sizeof(char*);
+
+ __fork_stack_begin = end;
+
+ __asm {mov esp,end };
+
+ set_stackbase(end);
+ heap_init();
+ }
+ else { // child process
+ stk = (char*)__fork_stack_begin + sizeof(char*)- mb - 65536;
+
+ dprintf("begin is 0x%08x\n",stk);
+ end = VirtualAlloc(stk, mb+65536 , MEM_RESERVE , PAGE_READWRITE);
+ if (!end) {
+ rc = GetLastError();
+ dprintf("virtual alloc 1 in child failed %d\n",rc);
+ return;
+ }
+ stk = VirtualAlloc(end, mb+65536 , MEM_COMMIT , PAGE_READWRITE);
+ if (!stk) {
+ rc = GetLastError();
+ dprintf("virtual alloc 2 in child failed %d\n",rc);
+ return;
+ }
+ end = stk + mb + 65536;
+ __asm {mov esp, end};
+ set_stackbase(end);
+
+ SetEvent(h64Child);
+
+ CloseHandle(h64Parent);
+ CloseHandle(h64Child);
+ }
+ }
+#endif _M_IX86
+
+
+ SetFileApisToOEM();
+
+ if (!bIsWow64Process)
+ heap_init();
+
+
+
+
+ /* If home is set, we only need to change '\' to '/' */
+ rc = GetEnvironmentVariable("HOME",buf,MAX_PATH);
+ if (rc && (rc < MAX_PATH)){
+ path_slashify(buf);
+ (void)SetEnvironmentVariable("HOME",buf);
+ goto skippy;
+ }
+
+ memset(ptr1,0,MAX_PATH);
+ memset(ptr2,0,MAX_PATH);
+ memset(ptr3,0,MAX_PATH);
+
+ if(osver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+ GetEnvironmentVariable("USERPROFILE",ptr1,MAX_PATH);
+ GetEnvironmentVariable("HOMEDRIVE",ptr2,MAX_PATH);
+ GetEnvironmentVariable("HOMEPATH",ptr3,MAX_PATH);
+
+ ptr1[MAX_PATH -1] = ptr2[MAX_PATH-1] = ptr3[MAX_PATH-1]= 0;
+
+#pragma warning(disable:4995)
+ if (!ptr1[0] || osver.dwMajorVersion <4) {
+ wsprintfA(temp, "%s%s",ptr2[0]?ptr2:"C:",ptr3[0]?ptr3:"\\");
+ }
+ else if (osver.dwMajorVersion >= 4) {
+ wsprintfA(temp, "%s",ptr1);
+ }
+#pragma warning(default:4995)
+ }
+ else if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
+
+ rc = GetWindowsDirectory(ptr1,MAX_PATH);
+ if (rc > MAX_PATH) {
+ MessageBox(NULL,"This should never happen","tcsh",MB_ICONHAND);
+ ExitProcess(0xFF);
+ }
+ (void)StringCbPrintf(temp,sizeof(temp),"%s",ptr1);
+ }
+ else {
+ MessageBox(NULL,"Unknown platform","tcsh",MB_ICONHAND);
+ }
+ path_slashify(temp);
+ SetEnvironmentVariable("HOME",temp);
+
+skippy:
+ gdwPlatform = osver.dwPlatformId;
+
+
+ rc = GetEnvironmentVariable("Path",path1,0);
+ if ( rc !=0) {
+
+ path1 =heap_alloc(rc);
+
+ GetEnvironmentVariable("Path",path1,rc);
+ SetEnvironmentVariable("Path",NULL);
+ /*SetEnvironmentVariable("PATH",NULL);*/
+ SetEnvironmentVariable("PATH",path1);
+
+ heap_free(path1);
+ }
+ mainCRTStartup(peb);
+}
+
+/*
+ * Copy source into target, quote if it has space, also converting '/' to '\'.
+ *
+ * hasdot is set to 1 if source ends in a file extension
+ * return value is the length of the string copied.
+ */
+int copy_quote_and_fix_slashes(char *source,char *target, int *hasdot ) {
+
+ int len ;
+ int hasspace;
+ char *save;
+ char *ptr;
+
+ save = target; /* leave space for quote */
+ len = 1;
+
+ target++;
+
+ hasspace = 0;
+ while(*source) {
+ if (*source == '/')
+ *source = '\\';
+ else if (*source == ' ')
+ hasspace = 1;
+
+ *target++ = *source;
+
+ source++;
+ len++;
+ }
+ ptr = target;//source;
+ while( (ptr > save ) && (*ptr != '\\')) {
+ if (*ptr == '.')
+ *hasdot = 1;
+ ptr--;
+ }
+
+ if (hasspace) {
+ *save = '"';
+ *target = '"';
+ len++;
+ }
+ return len;
+}
+/*
+ * This routine is a replacement for the old, horrible strcat() loop
+ * that was used to turn the argv[] array into a string for CreateProcess().
+ * It's about a zillion times faster.
+ * -amol 2/4/99
+ */
+char *concat_args_and_quote(char **args, char **poriginalPtr,char **cstr,
+ unsigned int *clen, char **cend, unsigned int *cmdsize) {
+
+ unsigned int argcount, arglen, cmdlen;
+ char *tempptr, *cmdend ,*cmdstr;
+ short quotespace = 0;
+ short quotequote = 0;
+ short noquoteprotect = 0;
+ char *tempquotedbuf;
+ unsigned long tqlen = 256;
+ int rc;
+
+ dprintf("entering concat_args_and_quote\n");
+ tempquotedbuf = heap_alloc(tqlen);
+
+ noquoteprotect = (short)(varval(STRNTnoquoteprotect) != STRNULL);
+ /*
+ quotespace hack needed since execv() would have separated args, but
+ createproces doesnt
+ -amol 9/14/96
+ */
+ cmdend= *cend;
+ cmdstr = *cstr;
+ cmdlen = *clen;
+
+ argcount = 0;
+ while (*args) {
+
+ *cmdend++ = ' ';
+ cmdlen++;
+
+ tempptr = *args;
+
+ arglen = 0;
+ argcount++;
+
+ //dprintf("args is %s\n",*args);
+ if (!*tempptr) {
+ *cmdend++ = '"';
+ *cmdend++ = '"';
+ }
+ while(*tempptr) {
+ if (*tempptr == ' ' || *tempptr == '\t')
+ quotespace = 1;
+ else if (*tempptr == '"')
+ quotequote = 1;
+ tempptr++;
+ arglen++;
+ }
+ if (arglen + cmdlen +4 > *cmdsize) { // +4 is if we have to quote
+
+
+ tempptr = heap_realloc(*poriginalPtr,*cmdsize<<1);
+
+ if(!tempptr)
+ return NULL;
+
+ // If it's not the same heap block, re-adjust the pointers.
+ if (tempptr != *poriginalPtr) {
+ cmdstr = tempptr + (cmdstr - *poriginalPtr);
+ cmdend = tempptr + (cmdend- *poriginalPtr);
+ *poriginalPtr = tempptr;
+ }
+
+ *cmdsize <<=1;
+ }
+ if (quotespace)
+ *cmdend++ = '"';
+
+ if ((noquoteprotect == 0) && quotequote){
+ tempquotedbuf[0]=0;
+
+ tempptr = &tempquotedbuf[0];
+
+ rc = quoteProtect(tempquotedbuf,*args,tqlen);
+
+ while(rc == ERROR_BUFFER_OVERFLOW) {
+ char *tmp = tempquotedbuf;
+ tempquotedbuf = heap_realloc(tempquotedbuf,tqlen <<1);
+ if(!tempquotedbuf) {
+ heap_free(tmp);
+ return NULL;
+ }
+ tqlen <<= 1;
+ tempptr = &tempquotedbuf[0];
+ rc = quoteProtect(tempquotedbuf,*args,tqlen);
+ }
+ while (*tempptr) {
+ *cmdend = *tempptr;
+ cmdend++;
+ tempptr++;
+ }
+ cmdlen +=2;
+ }
+ else {
+ tempptr = *args;
+ while(*tempptr) {
+ *cmdend = *tempptr;
+ cmdend++;
+ tempptr++;
+ }
+ }
+
+ if (quotespace) {
+ *cmdend++ = '"';
+ cmdlen +=2;
+ }
+ cmdlen += arglen;
+
+ args++;
+ }
+ *clen = cmdlen;
+ *cend = cmdend;
+ *cstr = cmdstr;
+
+ heap_free(tempquotedbuf);
+
+
+ return cmdstr;
+}
+char *fix_path_for_child(void) {
+
+ char *ptr;
+ Char *vp;
+ char *pathstr;
+ char *oldpath;
+ long len;
+
+ vp = varval(STRNTlamepathfix);
+
+ if (vp != STRNULL) {
+
+ len = GetEnvironmentVariable("PATH",NULL,0);
+
+ oldpath = heap_alloc(len+1);
+ pathstr = heap_alloc(len+1);
+
+ len = GetEnvironmentVariable("PATH",oldpath,len+1);
+ memcpy(pathstr,oldpath,len);
+
+ ptr = pathstr;
+ while(*ptr) {
+ if (*ptr == '/')
+ *ptr = '\\';
+ ptr++;
+ }
+ SetEnvironmentVariable("PATH",pathstr);
+ heap_free(pathstr);
+
+ return oldpath; //freed in restore_path;
+ }
+ else
+ return NULL;
+
+}
+void restore_path(char *oldpath) {
+ if (oldpath) {
+ SetEnvironmentVariable("PATH",oldpath);
+ heap_free(oldpath);
+ }
+}
diff --git a/win32/tcshrc.rc b/win32/tcshrc.rc
new file mode 100644
index 000000000000..e51f3e9b8c86
--- /dev/null
+++ b/win32/tcshrc.rc
@@ -0,0 +1,99 @@
+#if 0
+#include <windows.h>
+STRINGTABLE DISCARDABLE
+BEGIN
+666 " setenv EDITOR vi.exe"
+667 " setenv PAGER c:/bin/less"
+668 " setenv NOREBIND 1"
+669 " setenv LESS ""-B -c -h4 -i -M -q -x4 -G"""
+670 " setenv SHELL C:/bin/tcsh.exe"
+671 "if ($?PROCESSOR_ARCHITECTURE) then"
+672 " setenv USER $USERNAME"
+673 " setenv LOGNAME $USER"
+674 " setenv HOSTNAME $COMPUTERNAME"
+675 "endif"
+676 "umask 077"
+677 "if (! $?prompt) then # Everything else is interactive"
+678 " exit(0)"
+679 "endif"
+680 "unsetenv EXINIT"
+681 "if ($?tcsh) then"
+682 " set autolist"
+683 " set listlinks"
+684 " set pushdtohome"
+685 " set visiblebell"
+686 " set ellipsis"
+687 " set rmstar"
+688 "if ($?TERM) then"
+689 " if ($TERM == ""emacs"") then"
+690 " set prompt='%/\>'"
+691 " else"
+692 " set prompt='%{%}%c03%{%}\>'"
+693 " set prompt3='%{%}Correct to %R ?(y|n|e)%{%} '"
+694 " endif"
+695 "else"
+696 " set prompt='%{%}%c03%{%}\>'"
+697 " set prompt3='%{%}Correct to %R ?(y|n|e)%{%} '"
+698 "endif"
+699 " if ($?loginsh) then"
+700 " set correct=all"
+701 " set savedirs=100"
+702 " set autocorrect"
+703 " endif"
+704 " set complete=igncase"
+705 " complete which 'p/*/c/'"
+706 " complete where 'p/*/c/'"
+707 " complete start 'p/1/c/'"
+708 " complete cd 'p/1/d/'"
+709 " complete pushd 'p/1/d/'"
+710 " complete popd 'p/1/d/'"
+711 " complete bindkey 'p/*/b/'"
+712 " complete set 'p/*/v/'"
+713 " complete unset 'p/*/v/'"
+714 " bindkey -b ^W backward-delete-word"
+715 " bindkey -b ^U backward-kill-line"
+716 " bindkey -b ^R complete-word-fwd"
+717 " bindkey -b M-g list-glob"
+718 " bindkey -b M-* expand-glob"
+719 " bindkey -b M-v expand-variables"
+720 " bindkey -b M-w normalize-command"
+721 " bindkey -b M-/ e_dosify_prev"
+722 " bindkey -b M-r i-search-back"
+723 " bindkey -b M-x e_copy_to_clipboard"
+724 " bindkey -b M-y e_paste_from_clipboard"
+725 " bindkey -b N-up up-history"
+726 " bindkey -b N-down down-history"
+727 " bindkey -b N-right forward-char"
+728 " bindkey -b N-left backward-char"
+729 " bindkey -b N-del delete-char"
+730 " bindkey -b N-ins overwrite-mode"
+731 " bindkey -b N-1 which-command"
+732 " bindkey -b N-2 expand-history"
+733 " bindkey -b N-3 complete-word-raw"
+734 " bindkey -b N-home beginning-of-line"
+735 " bindkey -b N-end end-of-line"
+736 "endif"
+737 "if (! $?PATH_DONE) then"
+738 "set path=($path:q c:/bin .)"
+739 "setenv PATH_DONE 1"
+740 "endif"
+741 "set notify"
+742 "set noclobber"
+743 "set filec"
+744 "set history=(200) "
+745 "set savehist=(200 merge)"
+746 "set ignoreeof"
+747 "set fignore =(.obj .pdb .bsc .ilk .idb .OBJ .PDB .BSC .ILK .IDB)"
+748 "set color=(ls-F)"
+749 "alias ls ls-F "
+750 "alias h history"
+751 "alias rm c:/bin/rm.exe -i"
+752 "alias rd c:/bin/rmdir.exe"
+753 "alias md c:/bin/mkdir.exe"
+754 "alias mv C:/bin/mv.exe -i"
+755 "alias cp C:/bin/cp.exe -i"
+756 "alias pwd 'echo $cwd'"
+757 "alias env printenv"
+758 "alias unsave unset savehist savedirs"
+END
+#endif 0
diff --git a/win32/version.h b/win32/version.h
new file mode 100644
index 000000000000..44d425764877
--- /dev/null
+++ b/win32/version.h
@@ -0,0 +1,14 @@
+/*$Header: /p/tcsh/cvsroot/tcsh/win32/version.h,v 1.24 2008/09/10 20:34:21 amold Exp $*/
+#ifndef VERSION_H
+#define VERSION_H
+
+/* remember to change both instance of the version -amol */
+
+#ifdef NTDBG
+#define LOCALSTR ",nt-rev-8.10-debug"
+#else
+#define LOCALSTR ",nt-rev-8.10"
+ //patches
+#endif NTDBG
+
+#endif VERSION_H