[comp.unix.questions] rsh, rcp and the message "Where are you?"

gregg@quintus.UUCP (W. Gregg Stefancik) (11/06/87)

Has anyone else seen this?  When I do a rsh or rcp from certain accounts I
get the message "Where are you?" and then the remote command usually fails.
I can't seem to find any diffence between the accounts that have this
problem and those which don't.  Has anyone else seen this before and what
does it mean?

Gregg

forys@sigi.Colorado.EDU (Jeff Forys) (11/07/87)

I have sent mail on this to a couple people, I now present it here
in hopes that it will forever be remembered.  :-)

In article <173@tarski.quintus.UUCP> (W. Gregg Stefancik) writes:
> When I do a rsh or rcp from certain accounts I get the message
> "Where are you?" and then the remote command usually fails.

Rsh(1) invokes rshd(8C) on the target machine, this in turn starts up a
shell to execute your command.  Likewise, rcp(1C) (actually anything that
uses rcmd(3)) invokes rexecd(8C) on the target host, again starting up a
shell to execute your command.  Remember, by default, when a C shell is
started, your ~/.cshrc is sourced and any commands therein are executed.

With that out of the way, the error message "Where are you?" comes from
biff(1) when improperly placed in ~/.cshrc on the target machine.  Biff(1)
displays this message when it is unable to find its controlling terminal.
You should move the `biff' command to your ".login" to solve the problem.

A second, more obscure fix, is to put "if (! $?prompt) exit" near the top
of your ~/.cshrc.  Doing this prevents the remainder of your .cshrc from
being executed when not running in interactive mode (e.g. using a remote
shell).  This `feature' is used to expedite start up of remote shells...
---
Jeff Forys @ UC/Boulder Engineering Research Comp Cntr (303-492-4991)
forys@boulder.Colorado.EDU  -or-  ..!{hao|nbires}!boulder!forys

chris@mimsy.UUCP (Chris Torek) (11/12/87)

This (message from biff), by the way, points up the fact that
every program that prints error messages should also print its
own name.  If Gregg had seen

	% rcp otherhost:file here
	biff: Where are you
	%

he might at least have had *one* clue as to where to look.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

jbuck@epimass.EPI.COM (Joe Buck) (11/12/87)

In article <9312@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>This (message from biff), by the way, points up the fact that
>every program that prints error messages should also print its
>own name.  If Gregg had seen
>
>	% rcp otherhost:file here
>	biff: Where are you
>	%
>
>he might at least have had *one* clue as to where to look.

I remember grepping through the entire source once to find out
where that message was coming from, and being thoroughly annoyed.
And that was when I was at a site that had a source license!
Turns out a user put "biff y" in his .cshrc, same as here.

My present company only has binary, and buggy binary at that.
Suppose I could have done "strings" on everything.


-- 
- Joe Buck  {uunet,ucbvax,sun,decwrl,<smart-site>}!epimass.epi.com!jbuck
	    Old internet mailers: jbuck%epimass.epi.com@uunet.uu.net

mohamed@hscfvax.UUCP (750025@Mohamed_el_Lozy) (11/13/87)

One of my users was getting an "ioctl: operation not supported on socket"
or something very similar in one direction but not the other.  He had
a line with stty in .cshrc on one machine, in .login (where it belongs)
on the other.

jmsellens@watdragon.UUCP (11/13/87)

In article <9312@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>This (message from biff), by the way, points up the fact that
>every program that prints error messages should also print its
>own name.  If Gregg had seen
>
>	% rcp otherhost:file here
>	biff: Where are you
>	%
>
>he might at least have had *one* clue as to where to look.

And if biff had printed some sort of reasonable error message,
like "biff: standard error is not attached to a terminal"
it might be a useful error message.  And if that myriad of
programs that print "Who are you?" when they can't figure something
out printed something reasonable instead, the world would be a 
better place in which to live.

If I may, I would like to propose some error message guidelines,
which some of you undoubtedly will think of as obvious.

- Always always always put the program's name in the error message.
  And not the name you think it should be called, the argv[0] name
  that it actually was called.
- Don't use "cute" error messages (like the one above) - say what
  is really wrong.
- Always print error messages on the error output (stderr or 2).
- Don't print a message like "prog: can't open file", say which
  file you can't open, and why, as in:
    if ( ( fp = fopen( file, "r" ) ) == (FILE *) NULL ) {
	fprintf(stderr,"%s: can't open file '%s' for reading\n", argv[0],file);
	perror( argv[0] );  /* or use sys_errlist[errno] */
	exit(1);
    }
  i.e. Say what you can't do something to (the quotes are around
  it so that you can see if there are any extraneous spaces or tabs in
  the name), say what you can't do to it, and why.
- Always use exit() to set the exit status of your program.  If you
  don't call exit(0) at the end of main(), your program will exit
  with some random exit code, causing many to think that it failed
  somehow.


Sorry - if I stated the obvious.  I hate goofy "error" messages.

John

jc@minya.UUCP (John Chambers) (11/15/87)

In article <9312@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes:
> This (message from biff), by the way, points up the fact that
> every program that prints error messages should also print its
> own name.  If Gregg had seen
> 	% rcp otherhost:file here
> 	biff: Where are you
> 	%
> he might at least have had *one* clue as to where to look.

This is something I've tried to do since very early in my programming
career, after wasting *far* too much time just finding out the source
of several bizarre messages that nobody in the computer center could
explain.  But there is a serious problem with implementing it.

Imagine you are writing a function that is to be linked into any of 
a set of programs (or put into a library).  You have written a nice
validity test, and are typing an error message that looks like:
	fprintf(stderr,"%s: ..........\n",
Now what do you type?  How does a subroutine discover the name of
the program that called it?

If the function is called "main", the answer is easy: argv[0].  But
there is no law saying that argv[0] must be passed as a parameter to
every subroutine.

When I write programs, I usually include code like:
	char *progname="?";
	...
	main(argc,argv)
	...
		progname = argv[0];
	...
and then the subroutines that *I* write know where to find the name.
The designers of Unix/C, in their wisdom, saw fit to supply us with
a global environ[] so we can check the environment without permission
from main(), but I have never seen mention of a similar global pointer
that leads to the argv[] array.

If I've missed something in TFM, I'd love to hear about it.  Especially 
if it is portable to all Unices (or even better, to all Cs).

Waiting for flames about how dumb I've been....

-- 
John Chambers <{adelie,ima,maynard,mit-eddie}!minya!{jc,root}> (617/484-6393)

ok@quintus.UUCP (Richard A. O'Keefe) (11/16/87)

In article <365@minya.UUCP>, jc@minya.UUCP (John Chambers) writes:
> a global environ[] so we can check the environment without permission
> from main(), but I have never seen mention of a similar global pointer
> that leads to the argv[] array.

In every UNIX system I've used (that only includes ones where
sizeof (int) == sizeof (char*), but it includes PDP-11s, VAXen,
a couple of 68000s, and an 80386), there is a a chunk of memory
that looks like this:
		argc		: int		|  addresses
		argv[0]		: char*		|  increase
		...				:  going
		argv[argc-1]	: char*		|  down the
		NULL		: char*	       \|/ page
*environ -----> envv[0]		: char*
		...
		envv[last]	: char*
		NULL		: char*
I believe this was actually documented in one of the Version 7 manuals.
If you can't get at the argument list any other way, the following
function may be of use:

/*  arguments(int *pargc, char ***pargv)
    If this function can find the program's argv[] vector -- see
    execl(3) in the UNIX manual -- it sets *pargc to the number
    of arguments and *pargv to a pointer to the argv[] vector, and
    then returns 1.  If it cannot find the argument vector, it
    returns 0 without changing either argument.  The limit ARGMAX is
    a typical limit on the number of arguments which could have been
    passed.  If either argument is NULL that argument is not set.
    For example, to find the name the program was invoked as, do
	char **argv;
	if (arguments(NULL, &argv)) {
	    program_name = argv[0];
	}
*/

#define	ARGMAX 1024

int arguments(pargc, pargv)
    int *pargc;
    char ***pargv;
    {
	extern char **environ;
	char **p;
	int n;

	p = environ;
	if (!*--p) {
	    for (n = 0; n < ARGMAX; n++) {
		if ((int)*--p != n) continue;
		if (pargc) *pargc = n;
		if (pargv) *pargv = p+1;
		return 1;
	    }
	}
	return 0;
    }