Initial commit

This commit is contained in:
Matt Livingston 2020-09-08 15:16:08 +10:00
commit d429723a81
9 changed files with 125 additions and 0 deletions

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Matt Livingston
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

39
README.md Normal file
View File

@ -0,0 +1,39 @@
# Curlfish - The CRLF shell
This is **curlfish**, a program just about as simple as they come. The name comes from an expansion of an abbreviation of "CR/LF shell" (CRLF shell -> crlfsh - > curlfish)
What is a "CR/LF shell"? And why did I bother doing this? Well, years ago as a sysadmin, a user came to me with a puzzling error: his shell script was doing nothing but printing this error message `: File not found /bin/ksh`
This was decidedly odd, because `/bin/ksh` certainly did exist! After a little investigation, I discovered that he had transferred the file up to the unix server (running HP- UX 10.20, IIRC) via FTP from his windows desktop PC, and had done so in binary mode. Consequently, his script was full of CR/LF line endings, and when it ran, the shell found the shebang line `"#!/bin/ksh^M"` Naturally, when the shell could find no file of that name, it ceased executing the script, and printed this 4-part error message:
```
ksh: ./myscript: /bin/ksh^M: File not found
^ ^ ^ ^
1 2 3 4
```
Needless to say, the `^M` character was interpreted by the terminal as a carriage return, and the error message began overwriting itself from the start of the line. By a weird quirk of coincidence, part 4 of the error message was just long enough to completely overwrite parts 1 and 2 while leaving part 3 (mostly) intact, resulting in the slightly cryptic message shown earlier.
So I hit upon the idea of installing a program called `/bin/ksh^M` that merely printed a newline and an error message explaining exactly what must have happened and then exited. The result was **curlfish**
In fact, curlfish is little more than "Hello World!". The real hack is in the naming of files (filenames of symbolic links, actually). The actual binary is installed wherever you like (e.g. `/usr/local/bin`) and you make multiple symlinks to it, named exactly the same as real shells and script interpreters, except followed by a carriage return character. Thus, when a script file is created under an OS which uses CRLF line terminations by default, the script has a valid interpreter to call via its `#!` line.
For example:
```
/bin/ksh^M -> /usr/local/bin/curlfish
/bin/csh^M -> /usr/local/bin/curlfish
/usr/bin/perl^M -> /usr/local/bin/curlfish
/usr/local/bin/python^M -> /usr/local/bin/curlfish
(etc.)
```
Actually creating filenames with those characters is left as an exercise for the reader. There are several ways of doing so, and they all require some form of root access to create the symlinks that match the system-installed shells (at least, they _should_. Your system is pretty well b0rked if you can do this without root access).
I have also added a fairly distinctive return code (29), so that if scripts that call curlfish are called by methods other than a direct shell invocation, that fact can be tested for and the error handled gracefully. This might perhaps be useful in build systems.
So there it is at last, a somewhat practical use for a "Hello World!" program!
--
blubrick, 05/10/16 (code actually written _circa_ 2001)

14
curlfish.1 Normal file
View File

@ -0,0 +1,14 @@
.TH CURLFISH 1
.SH NAME
curlfish \- notify user if a script has DOS-style line endings
.SH SYNOPSIS
.B curlfish
[\fB\-h\fR] [script] [optional script parameters ignored]
.SH DESCRIPTION
.B curlfish
prints a message indicating either that the invoking script has CRLF line endings or that
.IR "this is not the shell you are looking for".
.SH OPTIONS
.TP
.BR \-h
Display a usage message

34
curlfish.c Normal file
View File

@ -0,0 +1,34 @@
/*
** This is curlfish, a program just about as simple as they come.
** The name comes from an abreviation of, then an expansion of, "CRLF shell"
** (CRLF SHELL -> crlfsh - > curlfish)
**
**
** In fact, the curlfish program is no more than "Hello World!". The real
** hack is in filenames (filenames of symbolic links, actually). The actual
** binary is installed in /bin and you make multiple symlinks to it, named
** exactly the same as real script interpreters, except followed by a carriage
** return character. Thus, when a file is created under DOS or Windows, and
** has CRLF line terminations, the script has a valid interpreter to call via
** its #! line.
**
** For example, A script is created under Windows which should call /bin/ksh,
** but because it has DOS style line terminations, it actually calls
** /bin/ksh^M Usually this results in a rather cryptic message indicating
** that the interpreter does not exist. A casual inspection of the file
** does not reveal the CRLF terminations, and the user checks that /bin/ksh
** does indeed exist. If /bin/ksh^M really does exist as a symlink to
** curlfish, the user is immediately made aware of the true nature of the
** problem.
**
** I have also added a fairly distinctive return code so that if scripts that
** call curlfish are called by methods other than a direct shell invocation,
** that fact can be tested for and the error handled gracefully.
**
*/
#include <stdio.h>
int main (void)
{
printf ("\n\nYour script contains DOS-style line endings\nPlease remedy the situation and try again\n\n");
return 29;
}

6
orig.sh Executable file
View File

@ -0,0 +1,6 @@
#!/arpa/af/b/blubrick/curlfish/sh
# Do some stuff
ls -la

1
sh Symbolic link
View File

@ -0,0 +1 @@
/bin/sh

1
sh Symbolic link
View File

@ -0,0 +1 @@
curlfish

6
test.sh Executable file
View File

@ -0,0 +1,6 @@
#!/arpa/af/b/blubrick/curlfish/sh
# Do some stuff
ls -la

3
testsh Executable file
View File

@ -0,0 +1,3 @@
#!/usr/bin/grsh
foo