orville-write-2.55/ 0040755 0000765 0000765 00000000000 10126436714 012375 5 ustar jan jan orville-write-2.55/README 0100644 0000765 0000765 00000017311 10126425625 013254 0 ustar jan jan ORVILLE WRITE PROGRAM - version 2.55
by Jan Wolter
The orville write program is a version of the standard Unix write program that
adds many nice features. It has been heavily used on M-Net since 1985, on
Grex since 1991 and on a few other systems. It is a ground-up
reimplementation using no proprietary code. The current version is quite
portable.
Write was written for use on M-Net and Grex, both public access unix systems in
Ann Arbor. As such, many of the features are designed to support a system
featuring a delicate mix of novice users and hostile pranksters, plus a lot of
people who just want to talk. It's user interface is pretty much identical to
the normal write program, but it offers many extensions and improvements:
- It is always possible to write someone who is writing you, even if his
permissions are off.
- Doing "write" without arguments replies to whoever is writing you.
Similarly if you do "write whoever" and whoever is logged in more than once
it will always write to the tty he is writing you from.
- Optionally, orville write can be configured to allow users to turn on write
permissions for only a selected list of users, or to turn off write
permissions for all but a selected list of users.
- If you write a person who is writing someone else, you will be asked if
you want to interupt before the connection is made.
- All control characters are expanded before sending them to the other user.
- When you disconnect, the user will receive an "EOF (your-login)" instead
of a simple "EOF". (This is done to aid users in identifying who just
did a "write whomever < /etc/termcap" to them. The identification at the
head of the messages scrolls off.)
- It is possible to set up a link to write (called, perhaps, "jot") that will
send each character to the other user as you type it. This is less boring
for the other user, since he doesn't have to sit there waiting for you to
finish a whole line before he has anything to read. However, it will not
go into character-by-character mode until the other person has replied.
(Since it's really annoying to have loose characters from someone chatting
you getting mixed into the output from other programs you are running.)
- It is possible to set up a link to write (called, perhaps, "tel") to send
quick one-line telegram messages to other users. Many people like to use
this as a way to hold a conversation by sending telegrams back and forth
while still doing something else on their terminals. You can always write
or tel a person for up to four minutes after he sent you a tel, even if
his permissions are off. There are provisions to prevent flooding people
with tels.
- Doing "write ." writes again to the last person you wrote. This is
especially handy with the "tel" command.
- Users can set a switch so write won't ring bells when a message is received.
- There is a facility for users to designate themselves as "helpers". Then
If a novice does "write help" he is connected to one of the helpers
currently not busy writing someone else. If there is more than one
candidate, one is selected at random to distribute the workload. It is
possible to configure the system so only users listed in a file may
designate themselves as helpers. Helpers can do "mesg -h y" to turn on
their helper status, or "mesg -h n" to turn it off. This is our main
mechanism for helping newusers on M-Net and Grex. We also have the
"finger" program display question marks by the names of users who are
helpers, though source for finger is not included in this package.
- There are two additional shell escapes. Doing "!ls" at the begining of
a line does the normal shell escape. Doing "|ls" sends the output to the
other user instead of to you. Doing "&ls" sends the output to both of you.
These are useful in instructing users about Unix commands through write
and for including files into your conversation (with "&cat file").
- When you receive a message from someone who is su'ed to some other account,
you are notified of both of his identities. The name from /etc/utmp is, of
course, the one you reply to, but on many systems this is not as reliable an
indicator of the identity of the person who is writing you as his uid, so
mentioning this name as well can reduce confusion.
- There is a configuration file, which an administrator can edit to among
other thing, disallow piping files through write by disabling the & and |
shell escapes and requiring standard input to the program to be a tty.
This is meant to be turned on when you have a temporary excess of twits
annoying other users.
- The "mesg" command may be used to set a flag telling the system to record
telegrams sent to you. If you have this turned on, the "huh" command will
redisplay the last message sent. This is useful when telegrams get
swallowed by other activity on your screen.
- It is possible to separately set "write" and "telegram" permissions with
the "mesg" command. Thus you can depermit telegrams being sent to you,
without depermitting writes. You can also specify a preference for being
writting in character mode or line mode.
- The "mesg" program may optionally be compiled to allow a disconnect
option. Doing "mesg N" (as opposed to "mesg n") will not only turn you
message permissions off, but disconnect anyone who is currently writing
you.
- There is an "amin" program (that's "am in", not the Ugandan guy), that lets
you do "amin vi filename". The runs "vi filename" normally, but if anyone
writes you while you are running that process, he will be told that you are
running "vi" and asked if he still wants to write you. "amin -n vi file"
just turns your message permissions off for the duration of the vi session.
"amin -np vi file" will record any telegrams anyone send you while you are
editing, and automatically display them when you are done editing.
CAVEATS: This program must run SUID-root or SGID-tty (where 'tty' is whatever
group the tty devices are on in your system). (Otherwise you couldn't write
people who are writing you even when their message perms are off.) Security
holes have been found in it from time to time over the years. I like to think
they've all been fixed now.
As mentioned in the HELPERS discussion, we have made some associated mods
to the finger program. The finger source I have is someone's cheap clone,
and is probably not useful for any serious modern Unix system. Someday I'll
do a set of patches for Gnu's finger.
Our original purpose in rewriting write was that our old system had people's
tty's writable to others when their message perms were on, and this led to
too much "cat /etc/termcap > /dev/tty04" kind of stuff. The orville write
program supports a choice of two different workarounds for that problem, but
neither is simple to install. You either have to modify login (and possibly
finger and other programs) or you have to live with some inconveniences. Of
course, nearly all modern Unix system don't have this problem (tty's are
owned by some "terminal" or "tty" group and only group permissions are ever
turned on). If you have one of those systems, or you don't mind leaving
tty's writable, there should be no problem installing write.
We've tried hard to make Orville write very portable. It should build easily
on almost all versions of Unix.
If you'd like a copy of the distribution goto Orville Write's homepage at
http:/www.unixpapa.com/write.html .
By the way, if you'd like to give M-Net or Grex a try, telnet arbornet.org or
cyberspace.org respectively (or aim your browser at them). Both systems give
away Unix accounts which may be used free of charge without validation.
orville-write-2.55/INSTALLATION 0100644 0000765 0000765 00000025237 07665700412 014232 0 ustar jan jan INSTALLATION INSTRUCTIONS
ORVILLE WRITE PROGRAM
Version 2.54
Jan Wolter
Installation of Orville write is fairly simple on most modern Unix systems.
1. Unpack the archive and cd into the directory.
2. If you have an really old Unix system, check that tty devices on your
system aren't permitted to others. Do
mesg y
ls -l `tty`
Normally you will see that your tty is permitted only to group, not to
others. If it is permitted to others, read the section at the end of
this file.
3. Run './configure'
There are lots of flags that can be given on the ./configure command,
but a few are worth special note:
--prefix=
default: /usr/local
--sysconfdir= default: PREFIX/etc
--bindir= default: PREFIX/bin
--mandir= default: PREFIX/man
Where the software will be installed. All the programs will be put
in bindir. The orville.conf file will be put in sysconfdir. The
manual pages will be put in mandir. It is especially important to
get sysconfdir set the way you want it before compiling, because
the location of the orville.conf file is compiled into all Orville
programs, so it cannot be moved without rebuilding the programs.
--with-talk
If you have a talk or ntalk program that has been modified to work
with Orville write, flick this switch.
--with-slow-passwd
If password file lookups on your system are slow (say you have lots
of users, and a non-hashed password database), setting this flag
will speed things up, but the writee won't be notified if the
writer's uid does not match his login name.
4. Run 'make'
This will build the 'write', 'mesg', 'amin' and 'helpers' programs.
5. Find the standard versions of write and mesg on your system. Depermit
them and move them to a safe place. You may want them back someday.
6. If you are upgrading from a previous version of Orville write, you may
want to save a copy of your old 'orville.conf' file. You should be
forwarned that users currently logged in will have some of their write
permissions reset to the default settings. This is because the format
of the 'wrttmp' file may change, and is thus emptied during each install.
7. Run 'make install' as root.
8. Edit the installed copy of the orville.conf file (which is, by default, in
/usr/local/etc/orville.conf). This is where most site configuration
is done.
If you enable any of the other files (write.log, write.help, write.nohelp,
helperlist), you must create them and put in sensible data.
If you don't plan to enable helpers, you could remove the helper program
and man page.
OTHER PROGRAMS
On M-Net and Grex, we have modifed 'finger' so that if a person is a helper,
a '?' is placed next to their tty (where the '*' would be if they're message
permissions were off). We have also modified ntalkd to respect Orville's
permissions. Neither of these modified programs is really in good enough
shape for general distribution at this point. Maybe later.
FILE PERMISSIONS
Orville write has a lot of files, whose permissions need to be set in
specific and rather odd ways. The install script should do things correctly.
For manual installers, here is a summary:
FILE OWNER GROUP PERMS
-----------------------------------
write root tty 6711
mesg root - 4711
amin root - 4711
huh root - 4711
helpers root - 4711
orville.conf root - 644
wrttmp root - 600
wrthist root - 600
* write.log root - 600
* write.help - - -
* helperlist - - -
* write.nohelp - - -
tty means whichever group owns all tty devices on your system.
- means I don't care.
* means this file is only used if you configure it into orville.conf
and is not installed by 'make install'
Note the decidedly odd permissions of the write program, which as suid root
as well as sgid tty. It really does need this, because it uses it's group
identity to check tty's for readability. I should probably change this
someday.
An alternate configuration with a few fewer suid-root programs. Maybe this
should be the default, I haven't had the time to work on figuring out how to
make the configure script work out the names of your tty group.
FILE OWNER GROUP PERMS
-----------------------------------
write root tty 6711
mesg root - 6711
amin - tty 2711
huh - tty 2711
helpers - tty 2711
orville.conf root - 644
wrttmp root tty 660
wrthist root tty 660
* write.log root - 600
The 'mesg' program can be made sgid-tty instead of suid-root if you don't
want to be able to turn on the 'disconnect' option in orville.conf.
If you make wrttmp and wrthist readable to others then you can get rid of a
sgid bits on 'huh' and 'helpers'. This allows people to figure out more
about how other users message permissions are set, and who they have been
writing recently. It's probably not worthwhile.
OLD-STYLE TTY PERMISSIONS
In the olden days, Unix systems were normally set up so that if you turned on
your message permissions, then your tty device was permitted to everyone.
The basic problem with systems of this type is that if you have your message
permissions on then people can do annoying things like send files to your
screen with:
cat /etc/termcap > /dev/yourtty
We had all too much trouble with this kind of frolicsome behavior on M-Net back
in 1985, and the original purpose of doing a re-implementation of write was to
block this kind of thing. That means changing the way tty permissions are
handled, and doing that is going to cause headaches because it effects every
program that does anything with tty permissions.
There are several options (A and D are the easy ones):
(A) Leave tty permissions working the same old way. People will still be
able to 'cat' garbage to your tty, but you won't have to worry about
modifying any other programs on your system and there will be no strange
side effects. This is not true of any of the other options below.
To use this option, edit the config.h file after running ./configure.
Remove the TTY_GROUP definition, and add the TTY_OTHERS definition.
Continue as above.
(B) Revise the tty permissions to work with group permissions as on the
systems described in the first part of this file. To do this you will
need, at a minimum, to modify the login program so it initially sets up
your tty permissions and group that way. Programs like "uucp", that just
need to be able to turn off write permissions, will work without change.
Programs like "pr" and "nroff" that turn off permissions while running
and then turn them on again afterwards could be a problem, because they
may turn the unwanted permissions to others back on. Other write-like
programs (talkd?) may have to be modified, though it is possible that you
may be able to get away with just running them SGID tty. If you go this
route, then the installation of write should be done as described in the
first section of this document. I've never tried converting a system
this way.
To use this option, build write just as above.
(C) Leave tty devices depermitted at all times, and have write store the
message permissions to be used in the /etc/wrttmp file, with the other
status information. This requires that the login program be modified
so that tty's are depermitted, though if you are any kind of guru dude,
you can make this fix without source by hacking argument to the chmod()
call in the binary (do people still do that?). This will have the odd
effect of having message permissions default OFF when people log in.
This is good for uucp, which doesn't like people writing it, but normal
users will need to put a "mesg y" in their .logins. Unless modified,
programs like "pr" will fail to turn off the message permissions when
they start, and then will throw your tty permissions wide open when they
finish. Other write-like programs may require even larger modifications
to work right.
To use this option, edit the config.h file after running ./configure.
Remove the both the TTY_GROUP definition and the TTY_OTHERS definition.
Continue as above.
(D) Leave tty devices depermitted at most times, and have write store the real
message permissions in the /etc/wrttmp file. You don't modify the login
program, so initially people's ttys will be writable to others. You
have the users put either "mesg y" or "mesg n" in their .login files.
As a side effect these will depermit the tty devices, so that for ever
afterwards no catting will be possible. Uucp will be fine, since all
message permissions in the wrttmp file initially default off, and the
uucp program turns off the tty device permissions itself. However
other programs that fiddle with tty permissions will still have problems
as in option C.
To use this option, edit the config.h file after running ./configure.
Remove the both the TTY_GROUP definition and the TTY_OTHERS definition.
Continue as above.
(E) Leave tty devices depermitted at all times, and have login initialize the
message permissions in the /etc/wrttmp file. Add code to the login
program to depermit the tty device and to make an appropriate entry in
the user's slot of the /etc/wrttmp file. Default the permissions on,
unless there is a file named ".mesgn" in the user's home directory. Give
uucp an ".mesgn" file. This actually what was done on M-Net while it was
still running under System III, but it isn't anymore. It's complicated,
but it does give you un-writable tty devices and message permissions that
default on for normal users. You still have the other incompatibility
problems mentioned in option C.
To use this option, edit the config.h file after running ./configure.
Remove the both the TTY_GROUP definition and the TTY_OTHERS definition.
Continue as above.
orville-write-2.55/CHANGES 0100644 0000765 0000765 00000013021 10126436474 013365 0 ustar jan jan Version 2.55: Sep 28, 2004
- Rename log() function to wrtlog() to avoid conflicts with math.h log()
function.
- Add distclean target to Makefile.
Version 2.54: May 30, 2003
- Fixed a couple buffer overrun problems that might have constituted a
possible security hole.
- Small portability fixes.
Version 2.53: Jul 6, 2000
- Minor portability improvements to install scripts.
Version 2.52: Jun 19, 2000
- Fixed a buffer overflow possibility in huh.c. This is a major problem if
'huh' is installed as root. Older versions should not be installed that
way.
Version 2.51: Feb 20, 2000
- Renamed lib_utmp.c as getutent.c, and cleaned it up to work more similarly
to the standard getutent() functions. Fixed some bugs Karyl Stein pointed
out with Linux utmp files.
Version 2.50: Jan 28, 2000
- Add -pk and -x* flags to mesg, so if we have a cooperative talkd, we can
control talk permissions seperately from write/tel permissions.
- Can optionally include hostnames in "Message from" headers.
- If a user is logged on more than once, write least idle tty.
- Use autoconf to generate ./configure script which makes Makefile and
and config.h.
- Replace old wrttab file with new orville.conf file, and move most site
configuration into there.
- Include timezone in message header, since sender's timezone is not
necessarily the same as the recipients.
- Lots of rearrangements of header files and such.
- Miscellaneous protability improvements.
- Write -r option supported for more different kinds of password files.
- Changed default name of the 'write -c' link to write from 'chat' to 'jot'.
Chat is a better name, and I had it first, but the other chat is more
widely distributed.
Version 2.41: Mar 17, 1999
- ANSIfication of all function declarations.
- Use getutent() on systems that have it. Need this when a utmp daemon
is used instead of a utmp file (thanks to Shane Wegner ).
- Be a bit more careful about printing/deleting .lastmesg to ensure we
aren't root when we do it.
- clean target added to Makefile (thanks to Shane Wegner ).
- Renamed "common.c" to "lib_common.c" because I wanted to.
- Lots of minor code cleanup.
Version 2.40:
- "mesg -bn" turns off bells.
- Fixed bug in disconnect so it disconnects multiple writes.
- exceptions through .yeswrite and .nowrite files and "mesg ye/ne" setting
- telegram mode no longer sets wrt_what, since it is too transient.
- telegram mode ignores -p, -y, -n, -c, -l flags (unless switch to write)
- added helpers command.
- Day of week in log file dates.
- mesg command prints warning if people still can write you.
- If previous helper is still available, another "write help" selects him.
- Disable core dumps and check that stderr is open.
- Security patches to .lastmesg file creation. [e]
- Security patches to .lastmesg reading. [f]
- Portability improvements to input flushing code
Version 2.34:
- Sizes of wrttmp entries stored in wrttmp header.
- Can write back to someone writing you even if he prefers tels.
- "mesg d" is like "mesg N" but doesn't change permissions.
- Linux bug fixes.
- Made writhist more resistant to system clock errors.
Version 2.33:
- Include uid name in message banner if different from utmp name.
- Root can override recipient's write/tel preferences.
- Optional recording of telegrams (with mesg -r, amin -p and huh)
- "mesg -hY" makes you a helper even when permissions are off.
Version 2.32:
- wrthist file added, permitting tel replys and regulating flooding.
- expand control-characters on local echo as well as send.
- teach it to echo tabs and backspaces more accurately.
- some low-grade word-wrap in character mode.
- HELPLOG option for logging help requests only.
Version 2.31:
- "write ." writes again to the last user written.
- write/telegram and line/character mode preferences added.
- support for login names with more than 8 characters.
- optional logging of all write requests.
- added -v to mesg. [2.31e]
- NOHELPER defines a file to print if there are no helpers. [2.31f]
Version 2.30:
- Integration of telegram option into write.
- Fix bug with shell escapes in "write -n" making "mesg n" perminant.
- Shell escapes use user's SHELL instead of always using /bin/sh.
Version 2.20:
- Reorganization of source code for greater modularity.
- If multiple helpers are available, choose one at random.
- When input is redirected, don't ask use stdin to ask user if he wants
to interupt a conversation.
- Don't go into character mode till other person has replied.
- Starting a line with ) in character mode does that line in line mode.
- If compiled with the NOVICEHELP variable and run with the NOVICE
environment variable set, prints the contents of the file named in
NOVICEHELP before running.
- Fixed amin's job control.
Version 2.11:
- If user is logged on more than once, prefer tty that is permitted.
- Clearer "Permission denied" message.
Version 2.12:
- Added TTY_OTHERS
Version 2.10:
- Attempted SYSV Compatible system.
- Added HELPERS
Version 2.00: First BSD Compatible system.
- Added wrttab.
- Added consistancy checking between utmp and wrttmp to eliminate need for
modifications to /bin/login.
- Added support for job control and other BSD-isms.
Version 1.05: Last M-Net system III specific version.
Version 1.00: First release - Sept 1985.
orville-write-2.55/wrt_main.c 0100644 0000765 0000765 00000025345 10126436545 014371 0 ustar jan jan /* suid WRITE command Version 2.50
*
* This is a replacement for the unix 'write' command with a large number of
* enhancements. See the manual page for details.
*
* (C) Copyright, Nov 1995 - Jan Wolter
*
* This program may be used, distributed and modified free of charge.
*
* History has been moved to "CHANGES" file.
*
* Acknowledgements: Russ Cage first implemented a version of the disconnect
* option, but his version of the source was lost. The reimplementation here
* is probably similar to his. The idea of helpers more or less originated
* with Eoin Cain. The telegram command was originally a separate command
* implemented in C by Jeff Spindler and improved by Russ Cage. Discussions
* with Marcus Watts were helpful in the design of the TTY_GROUP version.
* The record options were inspired by Jef Poskanzer's "say" command.
* Jim Knight installed zillions of versions on M-Net and added logging.
* Valerie Mates installed zillions of versions on Grex and sent back lots
* of valuable bug reports and suggestions. Jared Mauch supplied some
* Linux compatibility fixes. Input from John Remmers was useful in the
* design of the exception files. Shane Wegner made some patches to support
* use of getutent() and various installation scripts. Karyl Stein has
* supplied various good Linux bug fixes and reports. M-Netters and
* Grexers by the thousands have served (willy-nilly) as beta testers.
*/
char *version= "2.55";
#include "write.h"
#include
char linebuf[LBSIZE+1]; /* A place to stash lines of typed in stuff */
char *telmsg; /* Index of second word of telegram text in linebuf */
char myname[UT_NAMESIZE+1]= ""; /* my name (based on utmp file) */
char myuidname[UT_NAMESIZE+1]; /* my name (based on uid number) */
char *mytty; /* my tty name in "tty##" format */
#ifdef TTYPERMS
int myperms; /* my original tty perms */
#endif /*TTYPERMS*/
FILE *histerm; /* Opened version of device to write to */
struct wrttmp hiswrt; /* His wrttmp entry - later used for my tmp wrttmp */
char hisname[UT_NAMESIZE+1]= "";/* his name */
char histty[UT_LINESIZE+1]= ""; /* his tty name in "tty##" format */
char hisdevname[UT_LINESIZE+7]; /* Name of device to write to */
/* Mode flags are set by run time options */
bool char_by_char=FALSE;/* Run in character by character mode */
bool ask_root= FALSE; /* Ask for root password? */
bool telegram= FALSE; /* send a telegram? */
bool no_switch= FALSE; /* don't switch between tel and write? */
char tmp_mesg='s'; /* How to set messages while running: y, n or s */
bool postpone= FALSE; /* Postpone all tel interuptions */
bool am_root; /* Either uid is 0, or gave root passwd */
bool rec_only= FALSE; /* Do a postponed telegram, recorded, but not sent */
/* Exit flags tell what to do to restore sanity upon exiting */
bool fixed_modes= FALSE; /* On exiting, change wrttmp to mywrt? */
bool in_cbreak= FALSE; /* On exiting, get out of cbreak mode? */
bool is_writing= FALSE; /* On exiting, print goodbye message? */
bool insys= FALSE; /* Am I in | or & escape? */
bool readyn(void);
void type_help(char *file);
void wrtlog(char *outcome);
main(int argc, char **argv)
{
long pos;
struct wrttmp tmpwrt;
char hisperms;
extern struct wrttmp mywrt;
bool nl,file_input,replying= 0;
struct rlimit rlim;
char *tty;
int tmp;
/* Turn off signals while we are starting up - I don't remember why */
/* On the whole, probably a good idea */
sigoff();
/* Check that stdin/stdout/stderr all exist and are open (from mdw) */
if ((tmp=dup(0)) < 3)
{
/* We haven't got stderr, so don't print an error message. */
exit(25);
}
close(tmp);
#ifdef RLIMIT_CORE
/* Disable core dumps -- may have part of shadow password file in memory */
rlim.rlim_cur= rlim.rlim_max= 0;
setrlimit(RLIMIT_CORE, &rlim);
#endif
/* Set up options */
default_opts(argv[0]); /* Read options from orville.conf */
user_opts(argc,argv); /* Read options from command line */
file_input= !isatty(0);
if (!telegram && !file_input && f_novicehelp != NULL && getenv("NOVICE"))
type_help(f_novicehelp);
/* If -f has been specified, make sure standard input is a tty */
if (!f_pipes && file_input)
{
printf("%s: input from non-tty disabled\n",progname);
done(1);
}
/* Never allow standard output to be redirected - discourages tel bombs */
if (!isatty(1))
{
fprintf(stderr,"%s: standard output may not be redirected\n",progname);
done(1);
}
/* Get user's tty name safely */
if (getdevtty()) done(1);
mytty= mydevname+5;
#ifdef TTYPERMS
if (saveperms()) done(1);
#endif /*TTYPERMS*/
/* Set terminators on various names */
myname[UT_NAMESIZE]= hisname[UT_NAMESIZE]= histty[UT_LINESIZE]= '\0';
/* Open the wrttmp file */
if (init_wstream(O_RDWR))
done(1);
/* Set up ttynames and usernames and get our wrttmp entries */
find_us();
if (telegram) fflush(stdout);
nl= telegram;
if (!iswritable())
{
if (telegram) putchar('\n');
printf("Permission denied: %s is not accepting messages\n",hisname);
wrtlog("FAIL: denied");
done(1);
}
/* If he is busy, confirm that we want to interupt him */
if (*hiswrt.wrt_what != '\000' &&
!(replying= !strncmp(hiswrt.wrt_what,myname,UT_NAMESIZE)))
{
/* his mesgs are on, but he is writing someone else ... */
if (nl) putchar('\n');
nl= FALSE;
if (hiswrt.wrt_what[0] == '!')
printf("%s is running %0.*s\n",hisname,
UT_NAMESIZE-1, hiswrt.wrt_what+1);
else
printf("%s is now writing %0.*s.\n",
hisname, UT_NAMESIZE, hiswrt.wrt_what);
if (rec_only || (telegram && hiswrt.wrt_record == 'a'))
{
telegram= TRUE;
rec_only= TRUE;
}
if (rec_only)
printf("Do you want to leave %s message for when %s is done? ",
(telmsg == NULL || telmsg[0] == '\0' || telmsg[0] == '\n') ?
"a" : "your", hisname);
else
printf("Do you still want to write %s? ",hisname);
fflush(stdout);
if (!readyn())
{
wrtlog("ABANDON: interupting");
done(1);
}
}
/* Switch from tel to write (or vice versa) on recipient's preference */
if (!(am_root && no_switch) && !rec_only &&
(((telegram || file_input) && !(hiswrt.wrt_telpref & TELPREF_TEL)) ||
(!telegram && !(hiswrt.wrt_telpref & TELPREF_WRITE) && !replying)))
{
if (nl) putchar('\n');
nl= FALSE;
printf("%s is not accepting %ss.\n",
hisname, (telegram||file_input)?"telegram":"write");
if (!(hiswrt.wrt_telpref & (TELPREF_WRITE|TELPREF_TEL)) )
{
if (!no_switch) printf("Try the \042talk\042 command.\n");
wrtlog("FAIL: can't switch - talk only");
done(1);
}
if (no_switch || file_input)
{
if (!no_switch) printf("Try the \042write\042 command "
"(with no input redirection).\n");
wrtlog("FAIL: can't switch");
done(1);
}
else
{
printf("%s instead? ", telegram?"write":"send telegram");
fflush(stdout);
if (!readyn())
{
if (!am_root)
{
wrtlog("ABANDON: won't switch");
done(1);
}
}
else
telegram= !telegram;
}
printf("%s to %s on %s...\n", telegram?"Telegram":"Writing",
hisname, histty);
}
/* Switch between character and line mode on recipient's preference */
if (!telegram)
{
if (file_input)
char_by_char= FALSE;
else
{
if (char_by_char && hiswrt.wrt_modepref == 'l')
{
printf("[Changing to line mode by %s's preference]\n",hisname);
char_by_char= FALSE;
}
else if (!char_by_char && hiswrt.wrt_modepref == 'c')
{
printf("[Changing to character mode by %s's preference]\n",
hisname);
char_by_char= TRUE;
}
}
}
else
{
/* Turn off various options irrelevant to telegrams */
char_by_char= FALSE;
tmp_mesg= 's';
postpone= FALSE;
}
/* Open his terminal */
if (rec_only)
{
if ((histerm= fopen("/dev/null","w")) == NULL)
{
printf("%s:Panic - Cannot open /dev/null to write\n",progname);
done(1);
}
}
else
{
if ((histerm= fopen(hisdevname,"w")) == NULL)
{
printf("%s:Panic - Cannot open %s to write\n",progname,hisdevname);
done(1);
}
fcntl(fileno(histerm),F_SETFD,1); /* Close over execs */
}
if (telegram || file_input)
open_record();
open_hist();
wrtlog(rec_only?"POSTPONED":"OK");
/* Now that his terminal and the wrttmp file are open, abandon superuser */
setuid(getuid());
setgid(getgid());
/* Fix my entry in wrttmp */
set_modes();
/* Get rid of any previously recorded messages */
if (postpone) init_lastmesg();
siginit();
if (telegram)
dotelegram(nl);
else
dowrite();
done(0);
}
/* READYN - Read a "yes" or "no" from /dev/tty (in case stdin is redirected).
* Return TRUE if yes.
*/
bool readyn()
{
FILE *fp;
char ynbuf[LBSIZE];
if ((fp= fopen("/dev/tty","r")) == NULL) fp= stdin;
flushinput(fileno(fp));
fgets(ynbuf,LBSIZE,fp);
if (fp != stdin) fclose(fp);
return (*ynbuf == 'y' || *ynbuf == 'Y');
}
/* DONE -- This is the standard exit routine. It prints the EOF message (if
* we are actually writing the other user) and cleans up ttymodes and the
* wrttmp file.
*/
void done(int code)
{
extern FILE *recfp;
/* Put all those signals to sleep */
sigoff();
/* If we were writing, print the exit message */
if (is_writing && !nested_write())
{
fprintf(histerm,"EOF (%s)\n",myname);
fflush(histerm);
if (recfp) fprintf(recfp,"EOF (%s)\n",myname);
}
if (postpone) show_lastmesg();
/* If we changed our wrttmp entry, restore it */
reset_modes();
/* If we were in cbreak, restore old tty modes */
if (in_cbreak)
cbreak(FALSE);
exit(code); /* This should be the only call to exit() */
}
/* TYPE_HELP -- This prints out a help file.
*/
void type_help(char *file)
{
FILE *fp;
int ch;
if ((fp= fopen(file,"r")) != NULL)
{
while ((ch= getc(fp)) != EOF)
putchar(ch);
fclose(fp);
}
}
/* LOG - This logs a write execution.
*/
void wrtlog(char *outcome)
{
FILE *fp;
time_t tock;
extern bool helpseeker;
/* If we aren't logging, just get out */
if (f_loglevel == 0 || (f_loglevel == 1 && !helpseeker))
return;
/* If log file exist, open it, otherwise leave without creating it */
if (f_log == NULL || access(f_log,0) || (fp= fopen(f_log,"a")) == NULL)
return;
tock= time((time_t *)0);
if (helpseeker)
{
fprintf(fp,"%20.20s %-*.*s %s help (%s %s): %s\n",
ctime(&tock)+4,
UT_NAMESIZE, UT_NAMESIZE, myname,
progname,
(hisname[0] && strcmp(hisname,"help"))?hisname:"-",
histty[0]?histty:"-",
outcome);
}
else
{
fprintf(fp,"%20.20s %-*.*s %s %s %s: %s\n",
ctime(&tock)+4,
UT_NAMESIZE, UT_NAMESIZE, myname,
progname,
hisname[0]?hisname:"-",
histty[0]?histty:"-",
outcome);
}
fclose(fp);
}
orville-write-2.55/wrt_type.c 0100644 0000765 0000765 00000026114 07665676545 014445 0 ustar jan jan /* WRITE TYPING ROUTINES -- This does the actual write conversation, letting
* me type in characters and sending them to him. This whole module is too
* kludgy and needs a rewrite.
*/
#include "write.h"
#include
#include
#include
#if TIME_WITH_SYS_TIME
#include
#include
#else
#if HAVE_SYS_TIME_H
#include
#else
#include
#endif /* HAVE_SYS_TIME_H */
#endif /* TIME_WITH_SYS_TIME */
extern char eof_char, bs_char, kill_char;
extern bool helpseeker;
bool holdline; /* True if we don't want to send line till it is done */
struct passwd *getpwnam();
#ifndef HOTZONE
#define HOTZONE 9
#endif
#ifndef MAXLASTMESG
#define MAXLASTMESG 16000
#endif
FILE *recfp= NULL;
struct passwd *hispwd= NULL;
#define putb(ch) {putc(ch,histerm); if (recfp) putc(ch,recfp);}
#define putsb(st) {fputs(st,histerm); if (recfp) fputs(st,recfp);}
void backcol(int *col,int to);
void sendchar(int ch);
void sendline(char *ln, int start, int ind);
void sendbanner(void);
int isexcept(char *dir, int yesfile, char *login);
/* GETHISPWD - This routine ensures that the hispwd variable has been set.
* Returns true if it fails.
*/
int gethispwd()
{
if (hispwd != NULL) return (0);
return ((hispwd= getpwnam(hisname)) == NULL);
}
/* The following routines are for fooling with tabs and other multi-column
* characters. Column numbers are from 0 to 79.
*
* TABCOL(c) - If the cursor was in column c, this returns the column it would
* be in after hitting a tab.
*
* OUTCOL(str,i) - What column would the cursor appear in after typing the
* string from str[0] through str[n-1]?
*/
#define tabcol(c) (((c)+8)&(-8))
int outcol(char *str, int n)
{
int i,c= 0;
for (i= 0; i < n && str[i] != '\0'; i++)
{
if (!isascii(str[i]))
c+= isprint(toascii(str[i])) ? 3 : 4;
else if (str[i] == '\t')
c= tabcol(c);
else if (str[i] == '\b')
c--;
else if (!isprint(str[i]))
c+= 2;
else
c++;
}
return(c);
}
/* DOWRITE -- Do the actual write conversation */
void dowrite()
{
int ch;
int ind= 0; /* Current index into linebuf */
int start; /* Index of 1st unprinted char (during holdline only) */
int col= 0; /* Current column on screen */
int maxcol= get_cols(); /* Number of columns on screen (sort of) */
bool command= FALSE; /* True if we are doing a shell escape */
bool connected; /* True if the other person has replied (during
char_by_char mode only) */
/* send him a banner, if we weren't writing him already */
if (!nested_write())
sendbanner();
connected= !char_by_char; /* only character mode cares if connected */
is_writing= TRUE;
holdline= FALSE;
/* Go into cbreak mode, if that's what is desired */
if (char_by_char) cbreak(TRUE);
/* Start copying text from my terminal to his */
while((ch= getchar()) != EOF)
{
ch &= 0377;
if (char_by_char)
{
/* Fix odd backspace */
if (ch == bs_char)
ch= '\b';
/* low-grade word-wrap */
if ((!holdline || !connected) &&
(ch == ' ' || ch == '\t') &&
col > maxcol-HOTZONE && col < maxcol)
ch= '\n';
}
/* Echo the character in the line buffer */
switch(ch)
{
case '\n':
if (char_by_char) putchar(ch);
if (holdline)
{
if (command && ind > 0)
{
linebuf[ind]= '\000';
dosystem(linebuf);
}
else
{
linebuf[ind]= '\n';
sendline(linebuf,start,ind+1);
start= 1;
}
col= ind= 0;
continue;
}
col= ind= 0;
break;
case '\b': /* BACKSPACE */
if (char_by_char)
{
if (col == 0) continue;
if (ind > 0) ind--;
backcol(&col,outcol(linebuf,ind));
continue;
}
break;
case '\027': /* ^W */
if (char_by_char)
{
if (col == 0 || ind == 0) continue;
while (ind > 0 && isspace(linebuf[ind-1]))
ind--;
while (ind > 0 && !isspace(linebuf[ind-1]))
ind--;
backcol(&col,outcol(linebuf,ind));
continue;
}
case '\022': /* ^R */
if (char_by_char)
{
linebuf[ind]= '\000';
printf("\n%s",linebuf);
continue;
}
default:
if (ind == 0)
{
if (!connected && char_by_char && he_replied())
connected= TRUE;
command= (ch == '!' || ch == '|' || ch == '&');
holdline= (!connected || command || ch == ')');
start= (ch == ')') ? 1 : 0;
}
/* Simulate function of ^D for char_by_char mode */
if (ch == eof_char)
{
if (ind == 0)
return;
else
{
if (holdline)
{
linebuf[ind]= '\000';
if (command && ind > 0)
{
putchar('\n');
dosystem(linebuf);
ind= 0;
}
else
{
sendline(linebuf,start,ind);
start= ind;
}
}
continue;
}
}
if (ch == kill_char)
{
ind= 0;
backcol(&col,0);
continue;
}
if (ind < LBSIZE) linebuf[ind++]= ch;
if (char_by_char)
{
int tch= ch;
if (tch == '\t')
{
putchar(tch);
col= tabcol(col);
break;
}
if (!isascii(tch))
{
putchar('M');
putchar('-');
col+= 2;
tch= toascii(tch);
}
if (!isprint(tch))
{
putchar('^');
col++;
if (tch == '\177')
tch= '?';
else
tch+= '@';
}
putchar(tch);
col++;
}
break;
}
if (!holdline)
sendchar(ch);
}
}
/* DOTELEGRAM -- Send a telegram */
void dotelegram(bool nl)
{
int ch;
/* Ask the user for a message if we don't already have one */
if (telmsg == NULL || telmsg[0] == '\0' || telmsg[0] == '\n')
{
if (nl) putchar('\n');
printf("Msg: ");
fgets(telmsg= linebuf, LBSIZE, stdin);
if (telmsg[0] == '\n') done(0);
}
/* slow down if we are sending stuff too fast */
if (f_wrthist != NULL)
{
sleep(check_flood());
register_tel();
}
/* send him a banner, if we weren't writing him already */
if (!nested_write())
sendbanner();
/* Send the telegram */
is_writing= TRUE;
while (*telmsg != '\0')
sendchar(*(telmsg++));
if (rec_only)
printf("SAVED\n");
else
printf("SENT\n");
}
/* BACKCOL - Erase back until the current column col is to */
void backcol(int *col,int to)
{
for ( ; *col > to; (*col)--)
{
putchar('\b');
putchar(' ');
putchar('\b');
if (!holdline)
putsb("\b \b");
}
fflush(histerm);
}
/* SENDCHAR: Send a character to his tty, expanding out control characters,
* and storing a copy in the record file, if open.
*/
void sendchar(int ch)
{
if (ch == '\n' || ch == '\b' || ch == '\t' || ch == '\r')
putb(ch)
else
{
if (!isascii(ch))
{
putsb("M-");
ch= toascii(ch);
}
if (!isprint(ch))
{
putb('^');
ch= ((ch == '\177') ? '?' : ch + '@');
}
putb(ch);
}
fflush(histerm);
}
/* SENDLINE: Send a string to his tty, expanding out control characters.
* Start at start and go to ind. If ind is less than start, backspace to it.
*/
void sendline(char *ln, int start, int ind)
{
int i;
if (start < ind)
for (i= start; i < ind; i++)
sendchar(ln[i]);
else
{
for (i= start; i > ind; i--)
putsb("\b \b");
fflush(histerm);
}
}
/* SENDBANNER: Send a banner to him, notifying him that we want to talk
*/
void sendbanner()
{
time_t tock;
struct tm *tm;
char bf[300];
char *bell, *zone;
extern struct wrttmp hiswrt;
char host[1026];
#ifdef HAVE_TZNAME
extern char *tzname[2];
#endif
host[0]= '@';
if (f_fromhost && gethostname(host+1,1024))
f_fromhost= 0;
tock= time((time_t *)0);
tm= localtime(&tock);
#ifdef HAVE_TZNAME
if (tm->tm_isdst >= 0)
zone= tzname[tm->tm_isdst];
else
zone= NULL;
#else
#ifdef HAVE_TM_ZONE
zone= (char *)tm->tm_zone;
#endif
#endif
bell= (hiswrt.wrt_bells == 'y') ? "\007\007\007":"";
if (myuidname[0] == '\0')
sprintf(bf,"%s from %s%s%.90s on %s at %d:%02d %.20s ...\n%s",
telegram ? "Telegram" : "Message",
helpseeker ? "help-seeker " : "",
myname,
f_fromhost ? host : "",
mytty,
tm->tm_hour, tm->tm_min,
zone == NULL ? "" : zone,
bell);
else
sprintf(bf,
"%s from %s%s%.90s (%s) on %s at %d:%02d %.20s ...\n%s",
telegram ? "Telegram" : "Message",
helpseeker ? "help-seeker " : "",
myname,
f_fromhost ? host : "",
myuidname,
mytty,
tm->tm_hour, tm->tm_min,
zone == NULL ? "" : zone,
bell);
fputs(bf,histerm);
if (recfp) fputs(bf,recfp);
fflush(histerm);
}
/* OPEN_RECORD - Open a record file in the target users' home directory */
void open_record()
{
char fname[LBSIZE], *dir, *his_dir();
extern struct wrttmp hiswrt;
int fd;
struct stat st;
recfp= NULL;
if (hiswrt.wrt_record == 'n')
return;
if (gethispwd())
{
printf("%s: cannot find %s in passwd file -- not recording.\n",
progname,hisname);
if (rec_only) done(1);
return;
}
sprintf(fname,"%.400s/.lastmesg",hispwd->pw_dir);
/* First try to open an existing file */
if ((fd= open(fname, O_WRONLY|O_APPEND)) >= 0)
{
/* Check that .lastmesg file is owned by the right person */
if (fstat(fd,&st) ||
st.st_uid != hispwd->pw_uid ||
!(st.st_mode & 0200))
{
close(fd);
printf("%s: improper ownership of %s -- not recording.\n",
progname,fname);
if (rec_only) done(1);
return;
}
/* If we are recorded only most recent message, truncate file */
if (hiswrt.wrt_record == 'y')
{
ftruncate(fd,0L);
lseek(fd,0L,0); /* rewind (probably unnecessary) */
}
else if (lseek(fd,0L,1) > MAXLASTMESG) /* not a seek -- just tell */
{
printf("%s: %s overfull -- not recording.\n",progname,fname);
if (rec_only) done(1);
return;
}
}
else
{
/* Could not open existing file - try creating one */
if ((fd= open(fname,O_WRONLY|O_CREAT|O_EXCL|O_APPEND,0600)) < 0)
{
printf("%s: cannot open %s -- not recording.\n",
progname,fname);
if (rec_only) done(1);
return;
}
/* Set ownership of file to target user */
fchown(fd,hispwd->pw_uid,hispwd->pw_gid);
}
fcntl(fd, F_SETFD, 1); /* Close over execs */
recfp= fdopen(fd,"a");
}
/* ISHISEXCEPTION - is listed in the .yeswrite/.nowrite in HIS home
* directory?
*
* ISUEXECPTION - is listed in the .yeswrite/.nowrite in user's home
* directory?
*/
int ishisexception(int yesfile, char *login)
{
if (gethispwd()) return(0);
return(isexcept(hispwd->pw_dir, yesfile, login));
}
int isuexception(char *user, int yesfile, char *login)
{
struct passwd *pwd;
char u[UT_NAMESIZE+1];
/* Make sure the name is null terminated */
strncpy(u, user, UT_NAMESIZE);
u[UT_NAMESIZE]= '\0';
if ((pwd= getpwnam(u)) == NULL) return(0);
return(isexcept(pwd->pw_dir, yesfile, login));
}
int isexcept(char *dir, int yesfile, char *login)
{
char buf[LBSIZE+1];
char *b,*e;
FILE *fp;
sprintf(buf, "%.400s/%s", dir, yesfile ? ".yeswrite" : ".nowrite");
if ((fp= fopen(buf,"r")) == NULL) return(0);
buf[LBSIZE]= '\0';
while (fgets(buf,LBSIZE,fp) != NULL)
{
if (buf[0] == '#') continue;
e= buf-1;
for (;;)
{
/* Skip leading blanks and punctuation */
for (b= e+1;
*b!='\0' && strchr(" ,;:\t\n\r",*b)!=NULL; b++)
;
if (*b == '\0') break;
/* Find next blank or punctuation character */
for (e= b+1;
*e!='\0' && strchr(" ,;:\t\n\r",*e)==NULL; e++)
;
*e= '\0';
if (!strcmp(b,login))
{
fclose(fp);
return(1);
}
}
}
fclose(fp);
return(0);
}
orville-write-2.55/wrt_him.c 0100644 0000765 0000765 00000036451 10126426275 014221 0 ustar jan jan /* WRITE FINDHIM ROUTINES -- This searchs the wrttmp file for the person
* to write.
*/
#include "write.h"
#include
#include
#ifndef TCFLSH
#include
#endif /*TCFLSH*/
#ifdef HAVE_GETSPNAM
# define PW_GETSPNAM
# include
struct spwd *getspnam();
# ifdef HAVE_KG_PWHASH
char *pw_encrypt();
char *kg_pwhash(char *clear, char *user, char *result, int resultlen);
# else
# ifdef HAVE_PW_ENCRYPT
char *pw_encrypt();
# define pcrypt(l,p,s) pw_encrypt(p, s)
# else
# define pcrypt(l,p,s) crypt(p, s)
# endif
# endif
#else
# ifdef HAVE_GETUSERPW
# define PW_GETUSERPW
# define pcrypt(l,p,s) crypt(p, s)
# include
# else
# define PW_GETPWNAM
# define pcrypt(l,p,s) crypt(p, s)
# endif
#endif /* HAVE_GETSPNAM */
long hispos; /* The offset of his entry in the wrttmp file */
bool helpseeker= FALSE; /* Did we write to a random helper? */
char *what[2] = {"Writing", "Telegram"};
extern struct wrttmp hiswrt;
extern struct wrthdr wt_head;
void find_him(void);
int find_tty(void);
void find_answer(void);
void find_helper(void);
int perms_on(struct wrttmp *thewrt, time_t *atime);
/* Password encryption for Grex
*/
#ifdef HAVE_KG_PWHASH
char *pcrypt(char *login, char *plain, char *salt)
{
static char bf[40];
char *cpass;
if (salt[0] != '%')
cpass= pw_encrypt(plain, salt);
else if ((cpass= kg_pwhash(plain, login, bf, 40)) == NULL)
{
bf[0]= '\0';
cpass= bf;
}
return cpass;
}
#endif /* HAVE_KG_PWHASH */
/* FIXPERF: Fix old-style wrt_telpref fields in the given wrttmp structure.
*/
void fixpref(struct wrttmp *wrt)
{
if (wrt->wrt_telpref & TELPREF_OLD)
{
switch (wrt->wrt_telpref)
{
case 'w': wrt->wrt_telpref= TELPREF_WRITE; break;
case 't': wrt->wrt_telpref= TELPREF_TEL; break;
#ifdef WITH_TALK
case 'k': wrt->wrt_telpref= TELPREF_TALK; break;
#endif
case 'a': case '-': wrt->wrt_telpref= TELPREF_ALL; break;
}
}
}
/* FIND_US: This digs the two of us out of the utmp file and sets up myname,
* mytty, mydevname, mypos, hisname, histty, hisdevname and hispos.
*
* Finding myself is straightforward, but there are several cases for finding
* him:
* (1) Both name and tty are given: Check that that person is really
* on that tty.
* (2) Just the tty is given. Find the name on that tty, if any.
* (3) Just the name is given. Find all tty's occupied by someone by
* that name. If there are more than one, look for one who is
* writing me or one with his permissions on.
* (4) Neither name nor tty is given. Find if anyone is writing me.
* use that.
* (5) The name "help" was given. Find a helper who is not busy.
* (6) The name "." was given. Try writing to the last person written.
*
* If any of these fail, an appropriate error message is printed and
* we exit. If the succeed, a message is printed describing who we
* ended up writing.
*/
void find_us()
{
int rc;
extern struct wrttmp mywrt;
/* Open utmp file */
setutent();
/* Look me up */
find_me();
/* Find his name and wrttmp entry */
if (*hisname == '\0' && *histty == '\0')
{
/* No name was given - search wrttmp for someone writing me */
find_answer();
}
else if (f_helpers && *histty == '\0' && !strcmp(hisname,f_helpername))
{
/* Search for a helper who has his perms on and is not busy */
find_helper();
}
else if (*histty == '\0')
{
/* If name is "." get name from last field */
if (hisname[0] == '.' && hisname[1] == '\0')
{
if (mywrt.wrt_last[0] == '\0')
{
printf("No previous write or telegram. Can't repeat\n");
wrtlog("FAIL: no previous");
done(1);
}
strncpy(hisname,mywrt.wrt_last,UT_NAMESIZE);
}
/* Just the name given...look for him */
find_him();
}
else
{
if ((rc= find_tty()) > 0)
{
/* In telegram mode, if ttyname doesn't work, it is probably the
* first word of the message, and not the ttyname at all */
if (telegram)
{
telmsg= linebuf;
histty[0]= '\0';
if (hisname[0] == '\0')
find_answer();
else if (f_helpers && !strcmp(hisname,f_helpername))
find_helper();
else
find_him();
}
else if (rc == 1)
{
printf("No such tty\n");
wrtlog("FAIL: no such tty");
done(1);
}
else
{
printf("%s not logged onto %s\n",hisname,histty);
wrtlog("FAIL: not on tty");
done(1);
}
}
}
sprintf(hisdevname,"/dev/%.*s",UT_LINESIZE,histty);
fixpref(&hiswrt);
fixpref(&mywrt);
endutent();
}
/* FIND_HIM: Given just his name, search wrttmp for the person to write.
* If he is logged on more than once, we'll take any one of them, but we'd
* prefer one who is writing us, or at least has his perms on. If he isn't
* on, print an error message and exit.
*/
void find_him()
{
int cnt= 0;
int write_me;
int perm, hisperm= 0;
time_t hisatime= 0;
time_t atime;
struct utmp *ut;
struct wrttmp tmpwrt;
long tmppos;
setutent();
while ((ut= getutent()) != NULL)
{
/* Check if this is the target user, ignoring X-window lines */
if (ut->ut_line[0] != ':' &&
#ifdef USER_PROCESS
ut->ut_type == USER_PROCESS &&
#endif
!strncmp(hisname, ut->ut_name, UT_NAMESIZE))
{
/* Count matches */
cnt++;
/* Find wrttmp entry */
find_wrttmp(ut->ut_line, ut->ut_time, &tmpwrt, &tmppos);
/* Is this guy writing me? */
write_me= !strncmp(tmpwrt.wrt_what,myname,UT_NAMESIZE);
/* Do I have write access? How long has he been idle? */
if (!write_me)
perm= perms_on(&tmpwrt,&atime);
/* If writing me, is less idle, or is first to be permitted, save */
if (write_me || (perm && !hisperm) ||
(atime > hisatime && (perm == hisperm)) )
{
strncpy(histty, ut->ut_line, UT_LINESIZE);
hiswrt= tmpwrt;
hispos= tmppos;
hisatime= atime;
hisperm= perm;
/* If this guy is writing me, look no further */
if (write_me) break;
}
}
}
/* Check for abnormal results */
if (cnt == 0)
{
/* didn't find any matches, trouble */
printf("%s is not logged on\n",hisname);
{
wrtlog("FAIL: not on");
done(1);
}
}
else if (cnt == 1)
{
/* Found one match - the usual */
printf("%s to %s on %s...",what[telegram],hisname,histty);
if (!telegram) putchar('\n');
}
else
{
/* Found multiple matches -- tell which we used */
printf("%s logged on more than once\n",hisname);
printf("%s to %s...",what[telegram],histty);
if (!telegram) putchar('\n');
}
}
/* FIND_TTY: Given his ttyname, and possibly his login name, find a matching
* user. If none match, print an error message and exit. Set if hisname if
* it wasn't given. Return code:
* 0 - success.
* 1 - no such tty.
* 2 - named user not on named tty.
*/
int find_tty()
{
struct utmp *ut;
if ((ut= find_utmp(histty)) == NULL)
return(1);
if (*hisname != '\0')
{
/* Does the name not match? */
if (strncmp(hisname, ut->ut_name, UT_NAMESIZE))
return(2);
}
else
{
/* Is anyone on that line? */
if (*ut->ut_name == '\0')
{
printf("No one logged onto %s\n",histty);
wrtlog("FAIL: empty tty");
done(1);
}
strncpy(hisname, ut->ut_name, UT_NAMESIZE);
}
printf("%s to %s on %s...",what[telegram],hisname,histty);
if (!telegram) putchar('\n');
find_wrttmp(histty,ut->ut_time,&hiswrt,&hispos);
return(0);
}
/* FIND_ANSWER: Find a user who is writing me. Set up histty and hisname if
* a match is found. Note that if the time in the wrttmp entry doesn't match
* the time in the utmp entry, then we presume it is a dude wrttmp left over
* from some other login and we ignore it. If not found, print an error
* message and terminate.
*/
void find_answer()
{
struct utmp *ut;
int slot;
lseek(wstream,hispos= wrttmp_offset(slot= 0),0);
while (read(wstream, &hiswrt, sizeof(struct wrttmp)) ==
sizeof(struct wrttmp))
{
if (!strncmp(myname, hiswrt.wrt_what, UT_NAMESIZE))
{
/* Found someone writing me - get his name from utmp */
strncpy(histty,hiswrt.wrt_line,UT_LINESIZE);
if ((ut= find_utmp(histty)) != NULL && ut->ut_name[0] != '\0')
{
strncpy(hisname,ut->ut_name,UT_NAMESIZE);
printf("Replying to %s on %s...",hisname,histty);
if (!telegram) putchar('\n');
return;
}
}
lseek(wstream,hispos= wrttmp_offset(++slot),0);
}
printf("You are not being written\n");
wrtlog("FAIL: not written");
done(0);
}
/* FIND_HELPER: Find an unoccupied user who has his helper flag set. If
* found, set up histty and hisname. If there is none, print an error message
* and terminate. As usual, ignore wrttmp entries who's login times don't
* agree with the times in utmp. If there is more than one helper available,
* one is selected at random.
*/
void find_helper()
{
extern struct wrttmp mywrt;
int nhelpers= 0; /* Number of helpers on */
int ahelpers= 0; /* Number of helpers available */
int previous;
int slot= 0;
struct utmp *ut;
struct wrttmp tmpwrt;
long tmppos;
helpseeker= TRUE;
SEEDRAND((unsigned)time((time_t *)0));
for (;;)
{
/* Read in the next line of the file, remembering our offset */
lseek(wstream, tmppos= wrttmp_offset(slot++), 0);
if (read(wstream, &tmpwrt, sizeof(struct wrttmp)) !=
sizeof(struct wrttmp))
break;
/* Reject obvious non-helpers */
if (tmpwrt.wrt_help == 'n' || /* Helper flag off */
!strncmp(tmpwrt.wrt_line, mytty, UT_LINESIZE))
/* I can't help myself! */
continue;
/* Find the helper candidate in utmp - if he's not there skip out */
if ((ut= find_utmp(tmpwrt.wrt_line)) == NULL ||
ut->ut_name[0] == '\0' || ut->ut_time != tmpwrt.wrt_time)
continue;
/* Reject helpers with their message permissions off */
if (tmpwrt.wrt_help != 'Y')
{
if (!perms_on(&tmpwrt,NULL))
{
/* Perms off - but am I in .yeswrite file? */
if (!f_exceptions || tmpwrt.wrt_except != 'y' ||
!isuexception(ut->ut_name, 1, myname))
continue;
}
else
{
/* Perms on - but am I in .nowrite file? */
if (f_exceptions && tmpwrt.wrt_except == 'y' &&
isuexception(ut->ut_name, 0, myname))
continue;
}
}
/* Whoopie! We have found a real live helper */
nhelpers++;
/* Reject helpers who are busy writing someone else */
if (tmpwrt.wrt_what[0] != '\0' && /* He busy and ... */
strncmp(tmpwrt.wrt_what, myname, UT_NAMESIZE))
/* ...not writing me */
continue;
/* Zowie! He's not only there, he's available to help us */
ahelpers++;
/* Has he helped us before? */
previous= !strncmp(ut->ut_name, mywrt.wrt_last, UT_NAMESIZE);
/* So roll the dice to see if we will choose him */
if (!previous && (unsigned)RAND() > (unsigned)RAND_MAX / ahelpers)
continue;
/* We chose him, so make him our helper candidate so far */
strncpy(histty, tmpwrt.wrt_line, UT_LINESIZE);
strncpy(hisname, ut->ut_name, UT_NAMESIZE);
hiswrt= tmpwrt;
hispos= tmppos;
/* If he helped us before, choose him now */
if (previous) break;
}
if (ahelpers == 0)
{
if (nhelpers == 0)
{
printf("Sorry, no helpers are available right now.\n");
if (f_nohelp) type_help(f_nohelp);
wrtlog("FAIL: no helpers");
}
else
{
printf("Sorry, all helpers currently available are busy.\n");
if (f_nohelp) type_help(f_nohelp);
printf("Try again later...\n");
wrtlog("FAIL: help busy");
}
done(0);
}
printf("%s to helper %s on %s...",what[telegram],hisname,histty);
if (!telegram) putchar('\n');
}
/* PERMS_ON: Return true if permissions for the user whose wrttmp entry is
* passed in are on. This is a less thorough version of iswritable() used
* while selecting a user to write. Also returns last access time of tty, if
* atime is not null.
*
*/
int perms_on(struct wrttmp *thewrt, time_t *atime)
{
char devname[UT_LINESIZE+7];
struct stat stb;
short flag;
#ifndef TTYPERMS
if (atime != NULL || thewrt->wrt_mesg != 'n')
{
/* Even if wrttmp perms are off, user may still be writable if
* physical perms are on, so we need to stat the tty anyway in that
* case, or if we want the last access time.
*/
#endif /*TTYPERMS*/
/* Stat the terminal */
sprintf(devname,"/dev/%.*s",UT_LINESIZE,thewrt->wrt_line);
if (stat(devname,&stb))
{
printf("%s: Panic - can't stat %s\n",progname,devname);
done(1);
}
if (atime != NULL) *atime= stb.st_atime;
#ifndef TTYPERMS
}
if (thewrt->wrt_mesg != 'n')
return(TRUE);
#endif /*TTYPERMS*/
/* Is his tty physically writable? */
if (getuid() == stb.st_uid)
flag= stb.st_mode & 0200;
else if (getegid() == stb.st_gid || getgid() == stb.st_gid)
flag= stb.st_mode & 0020;
else
flag= stb.st_mode & 0002;
return(flag != 0);
}
/* ISWRITABLE: Check if he is writtable, either because his permissions are
* on, he is writing me, I am root, his tty is writable, or I can give the
* right root password with the -r option.
*/
bool iswritable()
{
char *cpass;
#ifdef PW_GETPWNAM
struct passwd *pwd;
#endif
/* Can I give the root password?
* We always test this first, so that we always ask for the root password
* when -r is given. This reduces the chance of accidentally sending the
* root password to the writtee because you expected it to ask for the
* root password and it didn't.
*/
if (ask_root)
{
#ifdef PW_GETPWNAM
pwd= getpwuid(0);
cpass= pcrypt("root",getpass("Password:"),pwd->pw_passwd);
flushinput(0); /* discard typeahead */
if (am_root= !strcmp(cpass,pwd->pw_passwd))
return (TRUE);
#endif
#ifdef PW_GETSPNAM
struct spwd *spwd;
spwd= getspnam("root");
cpass= pcrypt("root",getpass("Password:"),spwd->sp_pwdp);
flushinput(0); /* discard typeahead */
if (am_root= !strcmp(cpass,spwd->sp_pwdp))
return (TRUE);
#endif
#ifdef PW_GETUSERPW
struct userpw *upwd;
upwd= getuserpw("root");
cpass= pcrypt("root",getpass("Password:"),upwd->upw_passwd);
flushinput(0); /* discard typeahead */
if (am_root= !strcmp(cpass,upwd->upw_passwd))
return (TRUE);
#endif
printf("Password incorrect\n");
}
/* Is he writing me? */
if (!strncmp(hiswrt.wrt_what, myname, UT_NAMESIZE))
return(TRUE);
/* Am I already root? */
if (am_root= (getuid() == 0))
return(TRUE);
/* Are his permissions on? */
if (perms_on(&hiswrt,NULL))
{
/* Permissions are on, but are we an exception? */
if (!f_exceptions || hiswrt.wrt_except != 'y' ||
!ishisexception(0,myname))
return(TRUE);
}
else
{
/* Permissions are off, but are we an exception? */
if (f_exceptions && hiswrt.wrt_except == 'y' &&
ishisexception(1,myname))
return(TRUE);
}
if (f_wrthist != NULL && may_answer_tel())
return(TRUE);
/* Is he running "amin -p"? */
if (hiswrt.wrt_what[0] != '\0' && hiswrt.wrt_record == 'a')
{
/* NOTE: rec_only is only set if his perms are otherwise off.
* Later it gets set for all other cases too. */
rec_only= TRUE;
return(TRUE);
}
if (helpseeker && hiswrt.wrt_help == 'Y')
return(TRUE);
return(FALSE);
}
/* HE_REPLIED -- This routine returns true if the person we are writing appears
* to be writing us back. It should only be called after a call to find_us().
*/
bool he_replied()
{
struct wrttmp wbuf;
lseek(wstream, hispos, 0);
if (read(wstream, &wbuf, sizeof(struct wrttmp)) != sizeof(struct wrttmp))
return(FALSE);
return(!strncmp(wbuf.wrt_what, myname, UT_NAMESIZE));
}
orville-write-2.55/wrt_me.c 0100644 0000765 0000765 00000011720 07665673473 014057 0 ustar jan jan /* WRITE ROUTINES TO MANAGE MY WRTTMP ENTRY */
#include "write.h"
#include
#include
struct wrttmp mywrt; /* My old wrttmp entry, to be restored at exit time */
long mypos= -1; /* offset of my entry in the wrttmp file */
/* FIND_ME: Find my name and ttyline. Use these to dig up my wrttmp entry.
*/
void find_me()
{
struct utmp *ut;
struct passwd *pw;
int myuid;
/* Search utmp for myself */
if ((ut= find_utmp(mytty)) == NULL || ut->ut_name[0] == '\0')
{
printf("%s: Panic - Unable to find your tty (%s) in "_PATH_UTMP"\n",
progname, mytty);
done(1);
}
strncpy(myname, ut->ut_name, UT_NAMESIZE);
/* Check if this is our real identity */
#ifndef SLOWPASSWD
myuid= getuid();
if ((pw= getpwnam(myname)) == NULL || pw->pw_uid != myuid)
{
if ((pw= getpwuid(myuid)) == NULL)
{
printf("%s: Panic - No passwd file entry for uid %d (uname %s)\n",
progname,myuid, myname);
done(1);
}
strncpy(myuidname,pw->pw_name,UT_NAMESIZE);
myuidname[UT_NAMESIZE]= '\0';
}
else
#endif
myuidname[0]= '\0'; /* ie: myuidname is the same as myname */
/* Find my wrt_tmp entry */
find_wrttmp(mytty, ut->ut_time, &mywrt, &mypos);
}
/* SET_MODES: This sets our runtime modes into the wrttmp file and makes any
* temporary changes to our ttymodes. A copy of our original modes is left
* unchanged in mywrt and myperms. This is called as we go into write mode.
* For telegrams, the only change we make is to update the "last" field, if
* necessary. No transient changes are made.
*/
void set_modes()
{
struct wrttmp tmpwrt;
if (telegram)
{
/* If not writing same user again, update last field in wrttmp file */
if (strncmp(mywrt.wrt_last, hisname, UT_NAMESIZE))
{
strncpy(mywrt.wrt_last, hisname, UT_NAMESIZE);
lseek(wstream,mypos,0);
if (write(wstream,&mywrt,sizeof(struct wrttmp)) !=
sizeof(struct wrttmp))
{
printf("%s: Panic - Cannot write to wrttmp file\n",progname);
done(1);
}
}
}
else
{
/* Set last field - this should persist after we exit so do in mywrt */
strncpy(mywrt.wrt_last, hisname, UT_NAMESIZE);
tmpwrt= mywrt;
/* Make temporary changes to wrttmp entry */
strncpy(tmpwrt.wrt_what, hisname, UT_NAMESIZE);
tmpwrt.wrt_pid= getpid();
#ifdef TTYPERMS
setperms(tmp_mesg);
#else
if (tmp_mesg != 's') tmpwrt.wrt_mesg= mywrt.wrt_mesg;
#endif /*TTYPERMS*/
if (postpone) tmpwrt.wrt_record= 'a';
lseek(wstream,mypos,0);
fixed_modes= TRUE;
if (write(wstream,&tmpwrt,sizeof(struct wrttmp)) !=
sizeof(struct wrttmp))
{
printf("%s: Panic - Cannot write to wrttmp file\n",progname);
done(1);
}
}
}
/* UPDATE_MODES: This is called after a shell escape or a suspend to see if
* the user changed his message permissions while he was gone. If so, it
* copies the change into our copy of his old wrttmp entry so it will be
* restored to that after we exit write.
*/
void update_modes()
{
struct wrttmp tmpwrt;
#ifdef TTYPERMS
if (saveperms()) done(1);
#endif /*TTYPERMS*/
lseek(wstream,mypos,0);
if (read(wstream,&tmpwrt,sizeof(struct wrttmp))==sizeof(struct wrttmp))
{
strncpy(tmpwrt.wrt_last, mywrt.wrt_last, UT_NAMESIZE);
#ifndef TTYPERMS
mywrt.wrt_mesg= tmpwrt.wrt_mesg;
#endif /*TTYPERMS*/
mywrt.wrt_record= tmpwrt.wrt_record;
mywrt.wrt_telpref= tmpwrt.wrt_telpref;
mywrt.wrt_modepref= tmpwrt.wrt_modepref;
mywrt.wrt_help= tmpwrt.wrt_help;
mywrt.wrt_bells= tmpwrt.wrt_bells;
mywrt.wrt_except= tmpwrt.wrt_except;
}
}
/* RESET_MODES: Before exiting, restore wrttmp modes to original state (aside
* from any modifications made through update_modes()).
*/
void reset_modes()
{
if (fixed_modes)
{
lseek(wstream,mypos,0);
write(wstream,&mywrt,sizeof(struct wrttmp));
fixed_modes= FALSE;
#ifdef TTYPERMS
resetperms();
#endif /*TTYPERMS*/
}
}
/* NESTED_WRITE: Returns true if this write was run from within a write
* process with a shell escape
*/
bool nested_write()
{
return(!strncmp(mywrt.wrt_what, hisname, UT_NAMESIZE));
}
/* INIT_LASTMESG - Figure out what my lastmesg file is and empty it.
*/
char lmfile[100]= "";
void init_lastmesg()
{
char *dir;
struct passwd *pwd;
/* A little insurance that we aren't root anymore */
if (getuid() != geteuid())
return;
/* Try the environment variable first */
if ((dir= getenv("HOME")) == NULL)
{
/* Otherwise get directory from passwd file */
setpwent();
pwd= getpwuid(getuid());
endpwent();
if (pwd == NULL)
{
postpone= FALSE;
return;
}
dir= pwd->pw_dir;
}
sprintf(lmfile, "%.80s/.lastmesg", dir);
unlink(lmfile);
}
/* SHOW_LASTMESG - Print the .lastmesg file.
*/
void show_lastmesg()
{
FILE *fp;
int ch;
/* A little insurance that we aren't root anymore */
if (getuid() != geteuid())
return;
if (lmfile[0] == '\0' || (fp= fopen(lmfile,"r")) == NULL) return;
unlink(lmfile);
printf("Messages received while you were busy...\n");
while ((ch= getc(fp)) != EOF)
if (ch != '\007') putchar(ch);
}
orville-write-2.55/wrt_opt.c 0100644 0000765 0000765 00000010333 07044212343 014227 0 ustar jan jan /* WRITE OPTION ROUTINES -- Code to set options from orville.conf file or
* command line.
*/
#include "write.h"
/* SET_OPTS: Given a pointer to a string of one character option flags,
* terminated by a null or by white space, this sets the global variables
* corresponding to those flags. It returns 1 if any of the characters were
* illegal, 0 otherwise.
*/
int set_opts(char *str)
{
for(;;str++)
switch(*str)
{
case 'S':
no_switch= TRUE;
break;
case 'c':
char_by_char= TRUE;
break;
case 'l':
char_by_char= FALSE;
break;
case 'n':
case 'y':
case 's':
tmp_mesg= *str;
break;
case 'f':
f_pipes= FALSE;
break;
case 't':
telegram= TRUE;
break;
case 'r':
ask_root= TRUE;
break;
case 'p':
postpone= TRUE;
break;
case 'v':
fprintf(stderr,"Orville Write version %s\n",version);
break;
case '\0':
case '\n':
case '\t':
case ' ':
return(0);
default:
return(1);
}
}
/* SET_DFLT: Called for each "options" line in the configuration file. It
* is passed the rest of the line after the "options" keyword and any spaces.
* It checks if the filename matchs our program name, and if so, sets the
* options on that line.
*/
void set_dflt(char *p)
{
int len;
/* Does file line start with progname or a star? */
if (*p == '*')
p++;
else
{
len= strlen(progname);
if (!strncmp(progname,p,len))
p= p+len;
else
return;
}
/* Is that name followed by a space character? */
if (*p != ' ' && *p != '\t')
return;
/* Scan the rest of the line for dashes, and set anything after it */
for (p++ ;*p != '\n' && *p != '\0'; p++)
if (*p == '-' && set_opts(p+1))
fprintf(stderr,"%s: Unknown flag on options line in "
ORVILLE_CONF"\n", progname);
}
/* DEFAULT_OPTS: This reads through the orville.conf file loading configuration
* settings and looking for "options" lines that match progname. (Either
* progname itself or a "*"). If a match is found, the rest of the line is
* scanned for strings starting with a "-" that we can interpret as option
* flags. Those flags are set. Then we continue scanning for more matches.
*/
void default_opts(char *argname)
{
/* Strip leading components off invocation name of program */
progname= leafname(argname);
/* Use common reading routine */
readconfig(set_dflt);
}
/* USER_OPTS: This parses the command line arguments. It sets options, and
* also gets the name or tty of the person to write, if given. If there are
* problems in the argument syntax, then it prints a usage message. Note
* that with the telegram option, all arguments after the user name (possibly
* including the ttyname) are stuck into linebuf. telmsg is pointed at the
* part after the first word which might be the target tty rather than part
* of the message.
*/
void user_opts(int argc, char **argv)
{
int i;
char *c;
bool gotname=FALSE;
bool gottty=FALSE;
int wastelegram= telegram;
char *telegram_end= linebuf;
telmsg= NULL;
for (i=1; i UT_LINESIZE)
telmsg= linebuf;
else
strncpy(histty, c, UT_LINESIZE);
gottty= TRUE;
}
if (telegram)
{
if (telegram_end != linebuf)
{
*(telegram_end++)= ' ';
if (telmsg == NULL)
telmsg= telegram_end;
}
while (*c != '\0' & telegram_end < linebuf+LBSIZE-1)
{
*(telegram_end++)= *c;
/* Erase message words so they don't show on "ps" */
/* what needs to be done to do this varies on unixes */
/* but this should work most places */
*(c++)= ' ';
}
}
}
else
goto usage;
}
*(telegram_end++)= '\n';
*telegram_end= '\0';
return;
usage:
if (wastelegram)
printf("usage: %s [-ynsr] user [ttyname] [message...]\n",
progname);
else
printf("usage: %s [-clynsptr] user [ttyname]\n",progname);
done(1);
}
orville-write-2.55/wrt_sig.c 0100644 0000765 0000765 00000013214 07044212361 014210 0 ustar jan jan /* WRITE SIGNAL HANDLING ROUTINES -- Code to handle suspends and interputs and
* fun stuff like that, as well as the normal exit routines. Support for
* system calls is here too.
*/
#include "write.h"
#include
#include
#ifdef USER_SHELL
void wsystem(char *cmd);
FILE *wpopen(char *cmd, char *mode);
void xwpclose(void);
#define wpclose(s) xwpclose()
#else
#define wsystem(s) system(s)
#define wpopen(s,m) popen(s,m)
#define wpclose(s) pclose(s)
#endif
jmp_buf sysenv; /* Where to jump on intrupt during | and & escapes */
/* SIGINIT -- Set up the signal handler routines.
*/
void siginit()
{
signal(SIGTERM,(RETSIGTYPE (*)())intr);
signal(SIGINT,(RETSIGTYPE (*)())intr);
signal(SIGHUP,(RETSIGTYPE (*)())intr);
#ifdef JOB_CONTROL
signal(SIGTSTP,(RETSIGTYPE (*)())susp);
#endif /*JOB_CONTROL*/
}
/* SIGOFF -- Turn off all signals the signal handler routines.
*/
void sigoff()
{
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
signal(SIGTERM,SIG_IGN);
#ifdef JOB_CONTROL
signal(SIGTSTP,SIG_IGN);
#endif /*JOB_CONTROL*/
}
/* INTR -- Leave on an interupt. If the interupt was during a shell escape,
* resume as if the shell escape exited.
*/
RETSIGTYPE intr(int sig)
{
if (insys && (sig == SIGINT))
{
signal (SIGINT, (RETSIGTYPE (*)())intr);
longjmp(sysenv,1);
}
done(1);
}
/* SUSP -- Suspend the process. Unlike shell escapes, we restore the wrttmp
* entry before stopping. This is because, unlike shell escapes, we can't
* assume that stopped processes will be restarted in the reverse order in
* which they were stopped.
*/
#ifdef JOB_CONTROL
RETSIGTYPE susp()
{
int was_cbreak= in_cbreak;
int mask;
/* Disable further signals */
mask= sigblock(sigmask(SIGTSTP));
/* Restore modes and make wrttmp look like we exited */
if (in_cbreak) cbreak(FALSE);
if (postpone) show_lastmesg();
reset_modes();
signal(SIGTSTP,SIG_DFL);
sigsetmask(0);
kill(getpid(),SIGTSTP);
/* STOP HERE */
sigsetmask(mask);
signal(SIGTSTP,(RETSIGTYPE (*)())susp);
/* Reinstate cbreak mode and wrttmp entry */
if (was_cbreak) cbreak(TRUE);
update_modes();
if (!telegram) set_modes();
}
#endif /*JOB_CONTROL*/
/* DOSYSTEM: This routine does a system call of one of three types. If the
* first character is a "!" then we do the normal system call. If the first
* character is a "&" then we open a pipe to that command and send one copy
* of it's output to the other person, and one copy to me. If the first
* character is a "|" we only send the output to him.
*
* This routine absolutely must not be called until after we are no longer
* root. The wpopen() and wsystem() calls used here are not secure, even with
* full paths given.
*/
void dosystem(char *cmd)
{
char was_cbreak= in_cbreak;
FILE *pip, *wpopen();
int ch;
if (in_cbreak) cbreak(FALSE);
if (*cmd == '!')
{
wsystem(cmd+1);
}
else if (!f_pipes)
printf("%s: piped shell escapes disabled\n",progname);
else
{
if ((pip= wpopen(cmd+1,"r")) == NULL)
printf("%s:Panic - Unable to start command\n",progname);
else
{
if (!setjmp(sysenv))
{
insys= TRUE;
while((ch= getc(pip)) != EOF)
{
if (*cmd == '&') putchar(ch);
sendchar(ch);
}
}
insys= FALSE;
wpclose(pip);
}
}
/* Restore cbreak mode */
if (was_cbreak) cbreak(TRUE);
if (tmp_mesg == 's') update_modes();
printf("%c\n",*cmd);
}
#ifdef USER_SHELL
/* WSYSTEM: A modified version of the system() command that uses the user's
* own shell (as specified by the "SHELL" environment variable) instead of
* always using sh.
*/
void wsystem(char *cmd)
{
register int cpid,wpid;
RETSIGTYPE (*old_intr)(), (*old_quit)();
char *shell;
if ((cpid = fork()) == 0)
{
dup2(2,1);
/*setuid(getuid()); setgid(getgid());*/
endutent();
if ((shell= getenv("SHELL")) == NULL) shell= "/bin/sh";
execl(shell,leafname(shell),"-c",cmd,(char *)NULL);
fprintf(stderr,"%s: cannot execute shell %s\n", progname,shell);
exit(-1);
}
old_intr = signal(SIGINT,SIG_IGN);
old_quit = signal(SIGQUIT,SIG_IGN);
while ((wpid = wait((int *)0)) != cpid && wpid != -1)
;
signal(SIGINT,old_intr);
signal(SIGQUIT,old_quit);
}
/* WPOPEN/WPCLOSE - Run command on a pipe
*
* This is similar to the Unix popen() and pclose() calls, except
* (1) upopen() closes the last upopen() whenever it is called.
* (2) upclose() closes the last upopen(), and takes no args.
* (3) the user's own shell is used to process commands.
*/
FILE *f_lastpop = NULL; /* current upopened stream (NULL means none) */
int p_lastpop; /* process id of last upopened command */
FILE *wpopen(char *cmd, char *mode)
{
int pip[2];
register int chd_pipe,par_pipe;
FILE *fdopen();
char *shell;
if (f_lastpop) xwpclose();
/* Make a pipe */
if (pipe(pip)) return((FILE *)0);
/* Choose ends */
par_pipe= (*mode == 'r') ? pip[0] : pip[1];
chd_pipe= (*mode == 'r') ? pip[1] : pip[0];
switch (p_lastpop= fork())
{
case 0:
/* Child - run command */
close(par_pipe);
if (chd_pipe != (*mode == 'r'?1:0))
{
dup2(chd_pipe,(*mode == 'r'?1:0));
close(chd_pipe);
}
/*setuid(getuid()); setgid(getgid());*/
endutent(); /* Dunno if close-on-exec is set */
if ((shell= getenv("SHELL")) == NULL) shell= "/bin/sh";
execl(shell,leafname(shell),"-c",cmd,(char *)NULL);
fprintf(stderr,"%s: cannot execute shell %s\n", progname,shell);
exit(-1);
case -1:
close(chd_pipe);
close(par_pipe);
return((FILE *)0);
default:
close(chd_pipe);
return(f_lastpop=fdopen(par_pipe,mode));
}
}
void xwpclose()
{
int pid;
if (f_lastpop == NULL || fclose(f_lastpop)) return;
f_lastpop=NULL;
while ((pid=wait((int *)0)) != -1 && pid != p_lastpop )
;
}
#endif
orville-write-2.55/wrt_tty.c 0100644 0000765 0000765 00000007032 07042776222 014260 0 ustar jan jan /* WRITE TTY ROUTINES -- Routine to get user's tty in and out of cbreak mode.
*/
#include "write.h"
#ifdef F_TERMIO
#include
#endif /*F_TERMIO*/
#ifdef F_TERMIOS
#include
#endif /*F_TERMIOS*/
#ifdef F_STTY
#include
#endif /*F_STTY*/
#if !defined(TCFLSH) && !defined(TCIFLUSH)
#include
#endif
char eof_char; /* User's end of file character */
char bs_char; /* User's backspace character */
char kill_char; /* User's kill character */
/* CBREAK: cbreak(TRUE) turns on cbreak mode, cbreak(FALSE) restores the
* original tty modes.
*/
#ifdef F_STTY
void cbreak(bool flag)
{
struct tchars ctrlchars;
static struct sgttyb sgtty;
static tfg;
if (flag)
{
/* Get current modes */
ioctl(0,TIOCGETP,&sgtty);
tfg= sgtty.sg_flags;
bs_char= sgtty.sg_erase;
kill_char= sgtty.sg_kill;
ioctl(0,TIOCGETC,&ctrlchars);
eof_char= ctrlchars.t_eofc;
/* Remember that we are in cbreak mode */
in_cbreak= TRUE;
/* Turn on cbreak mode */
sgtty.sg_flags &= ~ECHO;
sgtty.sg_flags |= CBREAK;
ioctl(0,TIOCSETN,&sgtty);
}
else
{
/* Turn off cbreak mode - that is restore original modes */
sgtty.sg_flags= tfg;
ioctl(0,TIOCSETN,&sgtty);
in_cbreak= FALSE;
}
}
#endif /*F_STTY*/
#ifdef F_TERMIO
void cbreak(bool flag)
{
static struct termio tio;
static tfg;
static char eol_char;
if (flag)
{
/* Get current modes */
ioctl(0,TCGETA,&tio);
tfg= tio.c_lflag;
eof_char= tio.c_cc[VEOF];
eol_char= tio.c_cc[VEOL];
bs_char= tio.c_cc[VERASE];
kill_char= tio.c_cc[VKILL];
/* Remember that we are in cbreak mode */
in_cbreak= TRUE;
/* Turn on cbreak mode - that is turn off ICANON */
tio.c_lflag= tfg & ~ICANON;
tio.c_lflag &= ~ECHO;
tio.c_cc[VEOF]= 1;
tio.c_cc[VEOL]= 0;
ioctl(0,TCSETA,&tio);
}
else
{
/* Turn off cbreak mode - that is restore original modes */
tio.c_lflag= tfg;
tio.c_cc[VEOF]= eof_char;
tio.c_cc[VEOL]= eol_char;
ioctl(0,TCSETA,&tio);
in_cbreak= FALSE;
}
}
#endif /*F_TERMIO*/
#ifdef F_TERMIOS
void cbreak(bool flag)
{
static struct termios tio;
static tfg;
static char eol_char;
if (flag)
{
/* Get current modes */
tcgetattr(0,&tio);
tfg= tio.c_lflag;
eof_char= tio.c_cc[VEOF];
eol_char= tio.c_cc[VEOL];
bs_char= tio.c_cc[VERASE];
kill_char= tio.c_cc[VKILL];
/* Remember that we are in cbreak mode */
in_cbreak= TRUE;
/* Turn on cbreak mode - that is turn off ICANON */
tio.c_lflag= tfg & ~ICANON;
tio.c_lflag &= ~ECHO;
tio.c_cc[VEOF]= 1;
tio.c_cc[VEOL]= 0;
tcsetattr(0,TCSANOW,&tio);
}
else
{
/* Turn off cbreak mode - that is restore original modes */
tio.c_lflag= tfg;
tio.c_cc[VEOF]= eof_char;
tio.c_cc[VEOL]= eol_char;
tcsetattr(0,TCSANOW,&tio);
in_cbreak= FALSE;
}
}
#endif /*F_TERMIOS*/
/* FLUSHINPUT: Flush input on tty on filedescriptor dev.
*/
void flushinput(int dev)
{
#ifdef TCIFLUSH
tcflush(dev, TCIFLUSH); /* TERMIOS way to flush input */
#else
#ifdef TCFLSH
ioctl(dev,TCFLSH,0); /* SysIII way to flush input */
#else
int flushcode= FREAD;
ioctl(dev,TIOCFLUSH,&flushcode); /* BSD way to flush input */
#endif /*TCFLSH*/
#endif /*TCIFLUSH*/
}
/* GET_COLS: Return number of columns on user's terminal. Sort of. Since
* this is going to be used for wrapping on both my terminal and his, we
* won't let it be more than 80, since his terminal probably doesn't have
* more than 80 columns even if ours does.
*/
int get_cols()
{
#ifdef TIOCGWINSZ
struct winsize x;
ioctl(2,TIOCGWINSZ,&x);
if (x.ws_col == 0 || x.ws_col > 80)
return(80);
else
return(x.ws_col);
#else
return(80);
#endif
}
orville-write-2.55/wrt_hist.c 0100644 0000765 0000765 00000006410 07043367514 014407 0 ustar jan jan /* WRITE HISTORY ROUTINES -- Stuff to keep track of the last time I wrote
* various people and enforce rules about flooding.
*/
#include "write.h"
int hist_fd= -1; /* file descriptor for wrthist file */
struct wrthist myhist; /* Copy of my wrthist entry */
extern struct wrttmp hiswrt;
/* OPEN_HIST - Open the history file for read/write, if it is not already
* open.
*/
void open_hist()
{
if (hist_fd >= 0) return;
if ((hist_fd= open(f_wrthist,O_RDWR|O_CREAT,0600)) < 0)
{
printf("%s: Unable to open %s to read/write\n",
progname, f_wrthist);
done(1);
}
fcntl(hist_fd, F_SETFD, 1); /* close over execs */
}
/* EMPTY_HIST - blank out a history field to say no write has occurred for
* one heck of a long time.
*/
void empty_hist(hist)
struct wrthist *hist;
{
int i;
hist->tm= 0;
#if MAX_TEL_N > 1
for (i= 0; i < MAX_TEL_N - 1; i++)
hist->intv[i]= MAX_TEL_T + 1;
#endif
}
#ifdef DEBUG
/* PRINT_HIST - A debugging output routine */
void print_hist(struct wrthist *hist)
{
int i;
printf("last=%ld %s",hist->tm,ctime(&hist->tm));
printf("intervals=( ");
#if MAX_TEL_N > 1
for (i= 0; i < MAX_TEL_N - 1; i++)
printf("%d ",hist->intv[i]);
#endif
printf(")\n");
}
#endif
/* GET_HIST - Get the history file entry for the last times the person in
* slot "writer" wrote the person in slot "writee".
*/
void get_hist(long writer, long writee, struct wrthist *hist)
{
if (writee > MAXSLOTS)
{
empty_hist(hist);
return;
}
open_hist();
lseek(hist_fd,whindex(writer,writee),0);
if (read(hist_fd,hist,sizeof(struct wrthist)) !=
sizeof(struct wrthist))
empty_hist(hist);
}
/* PUT_HIST - Write the history file entry for the last times the person in
* slot "writer" wrote the person in slot "writee".
*/
put_hist(long writer, long writee, struct wrthist *hist)
{
if (writee > MAXSLOTS)
return;
open_hist();
lseek(hist_fd,whindex(writer,writee),0);
if (write(hist_fd,hist,sizeof(struct wrthist)) !=
sizeof(struct wrthist))
printf("%s: Error writing history entry\n",progname);
}
/* MAY_ANSWER_TEL - Check if he sent me a tel in the last f_answertel seconds.
*/
bool may_answer_tel()
{
int his_slot= hispos / sizeof(struct wrttmp);
int my_slot= mypos / sizeof(struct wrttmp);
struct wrthist hist;
get_hist(his_slot,my_slot,&hist);
return (hist.tm > hiswrt.wrt_time &&
time((time_t *)0) - hist.tm <= f_answertel);
}
/* CHECK_FLOOD - return a number of seconds we should sleep before sending
* another tel. This must be called before register_tel().
*/
int check_flood()
{
int his_slot= hispos / sizeof(struct wrttmp);
int my_slot= mypos / sizeof(struct wrttmp);
time_t now= time((time_t *)0);
int total;
int i,tmp,sft;
get_hist(my_slot,his_slot,&myhist);
if (myhist.tm > now) empty_hist(&myhist);
total= now - myhist.tm;
myhist.tm= now;
#if MAX_TEL_N > 1
sft= (total > MAX_TEL_T) ? MAX_TEL_T + 1 : total;
for (i= MAX_TEL_N-2; i >= 0; i--)
{
total+= myhist.intv[i];
tmp= myhist.intv[i];
myhist.intv[i]= sft;
sft= tmp;
}
#endif
return ((total >= MAX_TEL_T) ? 0 : MAX_TEL_T - total);
}
/* REGISTER_TEL() - Record that we did do a tel. Must be called after
* check_flood().
*/
void register_tel()
{
int his_slot= hispos / sizeof(struct wrttmp);
int my_slot= mypos / sizeof(struct wrttmp);
put_hist(my_slot,his_slot,&myhist);
}
orville-write-2.55/lib_common.c 0100644 0000765 0000765 00000021151 10126436611 014650 0 ustar jan jan /* ROUTINES COMMON BETWEEN WRITE, AMIN, MESG, ETC */
#include "orville.h"
#include
/* CONFIGURATION OPTION TABLE - various commands that can be set in the
* orville.conf file. The options are actually stored in the global variables
* declared here (with their default values). The conftab[] structure is used
* by the readconf() program to load them up easily.
*/
#define CO_OPT 0 /* 'options' command */
#define CO_STR 1 /* String-valued command */
#define CO_FLG 2 /* Flag-valued command */
#define CO_INT 3 /* Int-valued command */
char *f_wrttmp= D_WRTTMP; /* The who's-talking-to-whom file */
char *f_wrthist= D_WRTHIST; /* The who-talked-to-whom file */
char *f_novicehelp= NULL; /* Type this if "NOVICE" env var is defined */
char *f_log= NULL; /* Log for all write connections */
char *f_helperlist= NULL; /* File of users who may be helpers */
char *f_helpername= "help"; /* Name you write to get help */
char *f_nohelp= NULL; /* File to print if no helpers available */
int f_disconnect= TRUE; /* Does 'mesg d' disconnect users? */
int f_exceptions= TRUE; /* Do 'mesg ne' and 'mesg ye' work? */
int f_fromhost= FALSE; /* Include hostname in 'Message from' banner? */
int f_helpers= FALSE; /* Does 'write help' work? */
int f_pipes= TRUE; /* Can I cat files through write? */
int f_loglevel= 0; /* How much logging to do? */
int f_answertel= 240; /* How many seconds to answer telegrams? */
struct { char *cmd; int len; int type; void *var; } conftab[]= {
{"answertel", 9, CO_INT, (void *)&f_answertel},
{"disconnect", 10, CO_FLG, (void *)&f_disconnect},
{"exceptions", 10, CO_FLG, (void *)&f_exceptions},
{"fromhost", 8, CO_FLG, (void *)&f_fromhost},
{"helperlist", 10, CO_STR, (void *)&f_helperlist},
{"helpername", 10, CO_STR, (void *)&f_helpername},
{"helpers", 7, CO_FLG, (void *)&f_helpers},
{"log", 3, CO_STR, (void *)&f_log},
{"loglevel", 8, CO_INT, (void *)&f_loglevel},
{"nohelp", 6, CO_STR, (void *)&f_nohelp},
{"novicehelp", 10, CO_STR, (void *)&f_novicehelp},
{"options", 7, CO_OPT, NULL},
{"pipes", 5, CO_FLG, (void *)&f_pipes},
{"wrthist", 7, CO_STR, (void *)&f_wrthist},
{"wrttmp", 6, CO_STR, (void *)&f_wrttmp},
{NULL, 0, 0, NULL}};
char *progname; /* The name of this program */
int wstream; /* File descriptor for open wrttmp file */
struct wrthdr wt_head; /* Header read out of wrttmp file */
char mydevname[UT_LINESIZE+10]; /* my tty name in /dev/tty?? format */
/* LEAFNAME: return pointer to last component of a pathname */
char *leafname(char *fullpath)
{
char *leaf;
if ((leaf= strrchr(fullpath,'/')) == NULL)
leaf= fullpath;
else
leaf++;
return(leaf);
}
/* GETDEVTTY: Store the ttyname in the global mydevname variable.
* Print and error message and return non-zero if stderr not a tty open for
* read. This is to prevent people from pretending they are writing from a
* terminal other than their own by redirecting stderr to fool ttyname().
* They are unlikely to have read access to anyone else's tty.
*/
int getdevtty()
{
char *tty;
if (!(fcntl(2,F_GETFL,0) & O_RDWR) || !isatty(2))
{
printf("%s: stderr improperly redirected\n",progname);
return 1;
}
if ((tty= ttyname(2)) == NULL || strlen(tty) < 5)
{
printf("%s: Not on a valid tty\n");
return 2;
}
strncpy(mydevname,tty,UT_LINESIZE+10);
return 0;
}
/* INIT_WSTREAM - open the wrttmp file, loading and checking the header.
* Mode can be either O_RDONLY or O_RDWR. Prints error message and returns
* true if it fails.
*/
int init_wstream(int mode)
{
if ((wstream= open(f_wrttmp,mode)) < 0)
{
printf("%s: Unable to open %s to read/write\n", progname, f_wrttmp);
return(1);
}
fcntl(wstream,F_SETFD,1); /* Close over execs */
/* Read in wrttmp file header */
if (read(wstream,&wt_head,sizeof(struct wrthdr)) == sizeof(struct wrthdr))
{
if ( wt_head.hdr_size < sizeof(struct wrthdr) ||
wt_head.tmp_size < sizeof(struct wrttmp) )
{
printf("%s: %s file has undersized entries. Old version?\n",
progname, f_wrttmp);
return(1);
}
}
else
{
/* Initialize header for new wrttmp file */
wt_head.hdr_size= sizeof(struct wrthdr);
wt_head.tmp_size= sizeof(struct wrttmp);
if (mode != O_RDONLY)
{
lseek(wstream, 0L, 0);
write(wstream, &wt_head, sizeof(struct wrthdr));
lseek(wstream, 0L, 1); /* must seek between write and read */
}
}
return(0);
}
/* FIND_UTMP -- Find the named tty in the utmp file, returning NULL if we
* fail. The tty name need not be null terminated.
*/
struct utmp *find_utmp(char *tty)
{
struct utmp tmputmp;
strncpy(tmputmp.ut_line, tty, UT_LINESIZE);
setutent(); /* open and/or rewind */
return getutline(&tmputmp);
}
/* FIND_WRTTMP: Find the named tty in the wrttmp file and return the wrttmp
* field and the offset of that line's entry. If the entry's login time
* doesn't match the given one, or if there is no entry in the file, then
* return a default wrttmp entry instead. In the latter case, the position
* returned will be the offset of the first blank slot at the end of the file.
*/
void find_wrttmp(char *tty, time_t time,struct wrttmp *wbuf, long *pos)
{
register int slot;
slot= 0;
for(;;)
{
lseek(wstream, *pos= wrttmp_offset(slot++),0);
if (read(wstream, wbuf, sizeof(struct wrttmp)) != sizeof(struct wrttmp))
break;
if (!strncmp(tty, wbuf->wrt_line, UT_LINESIZE))
{
if (wbuf->wrt_time == time)
return;
else
break;
}
}
/* Set wbuf to default value */
dflt_wrttmp(wbuf,tty,time);
}
/* DFLT_WRTTMP -- set a wrttmp entry to default status */
void dflt_wrttmp(struct wrttmp *wbuf, char *tty, time_t time)
{
/* Set wbuf to default value */
strncpy(wbuf->wrt_line,tty,UT_LINESIZE);
wbuf->wrt_time= time;
wbuf->wrt_what[0]= '\0';
wbuf->wrt_last[0]= '\0';
wbuf->wrt_pid= -1;
wbuf->wrt_record= DFLT_RECO;
wbuf->wrt_telpref= DFLT_PREF;
wbuf->wrt_modepref= DFLT_MODE;
wbuf->wrt_bells= DFLT_BELL;
#ifndef TTYPERMS
wbuf->wrt_mesg= DFLT_MESG;
#endif /*TTYPERMS*/
wbuf->wrt_help= DFLT_HELP;
wbuf->wrt_except= DFLT_EXCP;
}
#ifdef TTYPERMS
int myperms; /* my original tty perms */
extern char mydevname[];
/* SAVEPERMS: Remember the current tty permissions of my terminal. Returns
* 1 on failure.
*/
int saveperms()
{
struct stat stb;
if (stat(mydevname,&stb))
{
printf("%s: Panic - can't stat %s\n",progname,mydevname);
return(1);
}
myperms= stb.st_mode;
return(0);
}
/* SETPERMS: Set the tty permissions to yes (perm='y'), no (perm='n'), or
* leave them alone (perm='s').
*/
void setperms(char perm)
{
if (perm == 'n')
chmod(mydevname,PERMS_OFF);
if (perm == 'y')
chmod(mydevname,PERMS_ON);
}
/* RESETPERMS: Set the tty permissions back to saved state.
*/
void resetperms()
{
chmod(mydevname,myperms);
}
#endif /*TTYPERMS*/
/* READCONFIG: This reads through the orville.conf file loading configuration
* settings. It calls set_dflt() on any 'options' lines it sees, and saves
* all configuration filenames. If set_dflt is NULL, it isn't called.
*/
void readconfig(void (*set_dflt)(char *))
{
FILE *fp;
#define BFSZ 1024
char buf[BFSZ+1];
int i;
char *p, *q;
if ((fp= fopen(ORVILLE_CONF,"r")) == NULL)
{
fprintf(stderr,"Unable to open "ORVILLE_CONF" to read\n");
exit(1);
}
while (fgets(buf,BFSZ,fp))
{
if (buf[0] == '#' || buf[0] == '\n') continue;
for (i= 0; conftab[i].cmd != NULL; i++)
{
if (strncmp(buf, conftab[i].cmd, conftab[i].len) ||
strchr(" \n\t\r", buf[conftab[i].len]) == NULL)
continue;
/* skip white space */
p= buf + conftab[i].len + 1;
while (*p != '\0' && strchr(" \t\n\r",*p) != NULL)
p++;
if (*p == '\0' || *p == '\n' || *p == '\r')
{
fprintf(stderr,"%s: No value given for %s in "
ORVILLE_CONF"\n", progname, conftab[i].cmd);
exit(1);
}
switch (conftab[i].type)
{
case CO_OPT: /* "options" command */
if (set_dflt != NULL)
(*set_dflt)(p);
break;
case CO_STR: /* string-valued commands */
/* Find end of word */
for (q= p; *q != '\0' && strchr(" \t\n\r",*q) == NULL; q++)
;
*q= '\0';
/* Save the new value, without freeing any previous value,
* which might be static.
*/
*(char **)conftab[i].var= malloc(q-p+1);
strcpy(*(char **)conftab[i].var,p);
break;
case CO_FLG: /* flag-valued commands */
*(int *)conftab[i].var= (*p == 'y' || *p == 'Y');
break;
case CO_INT: /* integer-valued commands */
*(int *)conftab[i].var= atoi(p);
break;
}
break;
}
}
fclose(fp);
}
orville-write-2.55/getutent.c 0100644 0000765 0000765 00000004602 07045473405 014403 0 ustar jan jan /* GETUTENT ROUTINES FOR SYSTEMS THAT HAVEN'T GOT THEM */
#include "orville.h"
#ifndef HAVE_GETUTENT
#include
static struct {
char *fname; /* Filename. If NULL, name is _PATH_UTMP */
int fd; /* file descriptor for open utmp file */
int state; /* 0 = not open; 1 = open; -1 = cannot open */
} utmp= {NULL,0,0};
/* OPENUTENT - Ensure the utmp file is open. Return non-zero if it can't be
* opened. This routine is not exported.
*/
static int openut()
{
if (utmp.state == 0)
{
if ((utmp.fd= open(utmp.fname ? utmp.fname : _PATH_UTMP,
O_RDONLY)) < 0)
{
utmp.state= -1;
return -1;
}
else
{
utmp.state= 1;
fcntl(utmp.fd, F_SETFD, 1); /* Close over execs */
return 0;
}
}
}
/* ENDUTENT - Close the utmp file.
*/
void endutent()
{
if (utmp.state == 1)
close(utmp.fd);
utmp.state= 0;
}
/* SETUTENT - Rewind the utmp file.
*/
void setutent()
{
if (utmp.state == 1)
lseek(utmp.fd, 0L, 0);
}
/* UTMPNAME - Set the name of the utmp file.
*/
int utmpname(const char *file)
{
/* Close any currently open file */
endutent();
if (utmp.fname != NULL) free(utmp.fname);
utmp.fname= strdup(file);
return 0;
}
/* GETUTENT - Read the next entry from the utmp file into static storage.
*/
struct utmp *getutent()
{
static struct utmp ut;
switch (utmp.state)
{
case 0:
openut();
/* Drop through */
case 1:
if (read(utmp.fd, &ut, sizeof(struct utmp)) == sizeof(struct utmp))
return &ut;
/* Drop through */
default:
return (struct utmp *)NULL;
}
}
/* GETUTLINE - Return utmp entry for the next entry in the utmp file whose
* ut_line field matches in->ut_line. It's obnoxious that this wants a
* whole utmp structure passed in instead of just a char pointer, but
* we conform with Linux and Solaris.
*/
struct utmp *getutline(const struct utmp *in)
{
static struct utmp ut;
switch (utmp.state)
{
case 0:
openut();
/* Drop through */
case 1:
while (read(utmp.fd, &ut, sizeof(struct utmp)) == sizeof(struct utmp))
{
if (
#if defined(USER_PROCESS) && defined(LOGIN_PROCESS)
(ut.ut_type == USER_PROCESS || ut.ut_type == LOGIN_PROCESS) &&
#endif
!strncmp(ut.ut_line, in->ut_line, UT_LINESIZE))
{
return &ut;
}
}
/* Drop through */
default:
return (struct utmp *)NULL;
}
}
#endif /* HAVE_GETUTENT */
orville-write-2.55/write.h 0100644 0000765 0000765 00000003312 07665675415 013715 0 ustar jan jan /* Standard header for all files that make up the Orville 'write' program */
#ifndef WRITE_H
#define WRITE_H
#include "orville.h"
#define LBSIZE 1024 /* Size of the input line buffer */
/* ======================== GLOBAL VARIABLES =========================== */
extern bool char_by_char, ask_root, fixed_modes, in_cbreak, is_writing,
insys, telegram, no_switch, am_root, rec_only, postpone;
extern char tmp_mesg;
extern char *progname, *mytty, *version, *telmsg;
extern char myname[], hisname[], hisdevname[], histty[], linebuf[];
extern char myuidname[];
extern FILE *histerm;
extern int wstream;
extern long hispos,mypos;
/* =================== PROCEDURE DEFINITIONS ===-----================== */
/* wrt_him.c functions */
void find_us(void);
bool iswritable(void);
bool he_replied(void);
/* wrt_hist.c functions */
void open_hist(void);
bool may_answer_tel(void);
int check_flood(void);
void register_tel(void);
/* wrt_main.c functions */
void done(int code);
/* wrt_me.c functions */
void find_me(void);
void set_modes(void);
void reset_modes(void);
bool nested_write(void);
void init_lastmesg(void);
void show_lastmesg(void);
/* wrt_opt.c functions */
char *leafname(char *fullpath);
void default_opts(char *argname);
void user_opts(int argc, char **argv);
/* wrt_sig.c functions */
void siginit(void);
void sigoff(void);
RETSIGTYPE intr(int sig);
RETSIGTYPE susp(void);
void dosystem(char *cmd);
/* wrt_tty.c functions */
void cbreak(bool flag);
void flushinput(int dev);
int get_cols(void);
/* wrt_type.c functions */
void dowrite(void);
void dotelegram(bool nl);
void open_record(void);
int ishisexception(int yesfile, char *login);
int isuexception(char *user, int yesfile, char *login);
#endif /* WRITE_H */
orville-write-2.55/wrttmp.h 0100644 0000765 0000765 00000013112 07043473533 014102 0 ustar jan jan /* WRTTMP FILE
*
* The wrttmp file consists of a single "wrthdr" entry, followed by multiple
* wrttmp entries. The wrttmp entries each describe one user on one tty line,
* and correspond to lines in the utmp file. "wrthdr" is mostly version info.
*
* This is the structure for each wrttmp file entry. Write can be configured
* to either use permissions stored in the wrtmp file, or to use the physical
* device permissions (if TTYPERMS is defined). The latter configuration is
* preferred, for easier coexistance with other programs, espeically if your
* old write program ran group "tty".
*
* Preferences (telegram vs write and line-mode vs character-mode) are also
* stored here. Normally these are set to "-" meaning that the choice is up
* to the sender. But if a preference is set by the reciever, it overrules
* the sender's choice.
*
* Also the name of the person currently being written is stored here. This is
* used by the auto-reply feature and the gizmo that asks about interupting.
*
* The name of the last person a telegram was sent to is also kept. This is so
* the next telegram can be sent to the same person.
*
* New entries in the wrthdr or wrttmp structures should be added to the end,
* leaving the old structures alone. This will ensure that the file can still
* be shared with programs compiled with an older version of wrttmp.
*/
#ifndef WRTTMP_H
#define WRTTMP_H
#include
#include
/* BSDI is only Unix I know of that threatens to change namesize from 8 to
* anything else. Most don't even have a define for it. Here we default
* NAMESIZE and LINESIZE to 8, if the operating system doesn't set them
* for us.
*/
#ifndef UT_NAMESIZE
#define UT_NAMESIZE 8
#endif
#ifndef UT_LINESIZE
#define UT_LINESIZE 8
#endif
#if defined(TTY_GROUP) || defined(TTY_OTHERS)
#define TTYPERMS
#endif
/* Weird alignment stuff borrowed from Marcus. Is it needed? */
#if defined(__GNUC__) && defined(WEIRD)
#define WORD_ALIGN __attribute__ ((packed))
#else
#ifdef _IBMR2
#pragma options align=twobyte
#endif
#define WORD_ALIGN /**/
#endif
struct wrthdr {
long hdr_size; /* sizeof(struct wrthdr) */
long tmp_size; /* sizeof(struct wrttmp) */
};
struct wrttmp {
char wrt_line[UT_LINESIZE]; /* a tty line */
char wrt_what[UT_NAMESIZE]; /* what this user is doing? */
char wrt_last[UT_NAMESIZE]; /* Who did he last write to? */
#ifndef TTYPERMS
char wrt_mesg; /* user's write perms (y or n) */
#endif /*TTYPERMS*/
char wrt_record; /* Should we record tels? y, n, or a */
char wrt_telpref; /* user's program prefs (TELPREF_*) */
char wrt_modepref; /* user's mode prefs (c, l or -) */
char wrt_help; /* user is a helper? y or n */
int wrt_pid WORD_ALIGN; /* our process id */
time_t wrt_time WORD_ALIGN; /* should match ut_time in utmp file */
char wrt_bells; /* ring bells? y or n */
char wrt_except; /* use exception file? y or n */
};
/* wrt_telperf bit masks: If TELPREF_OLD is set, then wrt_telperf has one of
* the following values:
* '-' any program - equivalent to new value 0
* 'w' write program only - equivalent to new value TELPREF_WRITE
* 't' tel program only - equivalent to new value TELPREF_TEL
* If TELPREF_OLD is not set, then any of the programs whose bits are set are
# acceptable.
*/
#define TELPREF_OLD 0x20 /* Use old-style flag value */
#define TELPREF_WRITE 0x01 /* Accept writes */
#define TELPREF_TEL 0x02 /* Accept tels */
#ifdef WITH_TALK
#define TELPREF_TALK 0x04 /* Accept talks */
#define TELPREF_ALL (TELPREF_WRITE | TELPREF_TEL | TELPREF_TALK)
#else
#define TELPREF_ALL (TELPREF_WRITE | TELPREF_TEL)
#endif
#ifdef _IBMR2
#pragma options align=reset
#endif
/* These are the tty modes to use when permissions are on and off */
#define PERMS_OFF 0600 /* To depermit everything */
#define PERMS_OPEN 0622 /* To allow cats to your device */
#ifdef TTY_OTHERS
#define PERMS_ON PERMS_OPEN /* To allow writes and telegrams and what not */
#else
#define PERMS_ON 0620 /* To allow writes and telegrams and what not */
#endif /*TTY_OTHERS*/
/* Initial (at login) settings of various flags in wrttmp */
#define DFLT_MESG 'n' /* this effects only TTYPERMS versions */
#define DFLT_HELP 'n'
#define DFLT_RECO 'n'
#define DFLT_MODE 'a'
#define DFLT_PREF TELPREF_ALL
#define DFLT_BELL 'y'
#define DFLT_EXCP 'n'
/* Offset of the nth entry in the wrttmp file */
#define wrttmp_offset(n) (wt_head.hdr_size + (n)*wt_head.tmp_size)
/* WRTHIST file
*
* The wrthist file keeps track of when each user last wrote each other user.
* It is used to allow telegrams to be sent to people who recently sent you
* telegrams, even if their permisions are off, and enforce rules about
* flooding -- repeatedly sending many telegrams in a short period of time.
*
* It functions as a two dimensional array indexed by my slot number and
* his slot number. Slot numbers are the index our wrttmp entry have in the
* wrttmp file. It's like an array "struct wrthist table[][MAXSLOTS], where
* the first index is myslot number and the second is his slot number.
*/
#ifndef MAXSLOTS
#define MAXSLOTS 512
#endif
/* At most MAX_TEL_N telegrams may be sent in any MAX_TEL_T second period */
#ifndef MAX_TEL_T
#define MAX_TEL_T 25
#endif
#ifndef MAX_TEL_N
#define MAX_TEL_N 4
#endif
struct wrthist {
time_t tm; /* last time I wrote him */
#if MAX_TEL_N > 1
unsigned short intv[MAX_TEL_N-1]; /* intervals to pervious times */
#endif
};
/* Location of slot describing last time a wrote b -- b should be < MAXSLOTS */
#define whindex(a,b) (long)((a * MAXSLOTS + b) * sizeof(struct wrthist))
#endif /* WRTTMP_H */
orville-write-2.55/orville.h 0100644 0000765 0000765 00000003540 07044463314 014222 0 ustar jan jan /* Standard header for all Orville Write programs */
#ifndef ORVILLE_H
#define ORVILLE_H
#include "config.h"
#include
#ifdef HAVE_FCNTL_H
# include
#endif
#ifdef STDC_HEADERS
# include
# include
#else
# ifndef HAVE_STRCHR
# define strchr index
# define strrchr rindex
# endif
char *strchr(), *strrchr(), *getenv(), *malloc();
#endif
#ifdef HAVE_SYS_TIME_H
# include
#else
# include
#endif
#ifdef HAVE_CRYPT_H
# include
#endif
#ifdef HAVE_UNISTD_H
# include
char *getpass(); /* Some unistd's don't define this - foo */
#else
char *getpass(), *ttyname();
# ifndef HAVE_CRYPT_H
char *crypt();
# endif
#endif
#include "wrttmp.h"
#include "lib_common.h"
typedef char bool; /* Boolean type */
#define TRUE 1
#define FALSE 0
/* Method to set cbreak/cooked modes */
#ifdef HAVE_TERMIOS_H
# define F_TERMIOS
#else
# ifdef HAVE_TERMIO_H
# define F_TERMIO
# else
# ifdef HAVE_SGTTY_H
# define F_STTY
# endif /* HAVE_SGTTY_H */
# endif /* HAVE_TERMIO_H */
#endif /* HAVE_TERMIOS_H */
/* Random Number Generator */
#ifdef HAVE_RANDOM
# define RAND() random()
# define SEEDRAND(x) srandom(x)
# ifndef RAND_MAX
# define RAND_MAX 2147483647
# endif
#else
# define RAND() rand()
# ifndef RAND_MAX
# define RAND_MAX 32767
# endif
# define SEEDRAND(x) srand(x)
#endif /* HAVE_RANDOM */
#define JOB_CONTROL /* support job-control */
#define USER_SHELL /* shell escapes run with user's shell */
/* These are the tty modes to use when permissions are on and off */
#define PERMS_OFF 0600 /* To depermit everything */
#define PERMS_OPEN 0622 /* To allow cats to your device */
#ifdef TTY_OTHERS
# define PERMS_ON PERMS_OPEN /* To allow writes and talks and what not */
#else
# define PERMS_ON 0620 /* To allow writes and talks and what not */
#endif /*TTY_OTHERS*/
#endif /* ORVILLE_H */
orville-write-2.55/lib_common.h 0100644 0000765 0000765 00000001452 07045471726 014673 0 ustar jan jan /* Header file for routines common between write, amin, mesg, etc */
#ifndef LIB_COMMON_H
#define LIB_COMMON_H
#include "getutent.h"
int init_wstream(int mode);
struct utmp *find_utmp(char *tty);
void find_wrttmp(char *tty, time_t time,struct wrttmp *wbuf, long *pos);
void dflt_wrttmp(struct wrttmp *wbuf, char *tty, time_t time);
char *leafname(char *fullpath);
int mydevtty(void);
extern char *f_wrttmp, *f_wrthist, *f_novicehelp, *f_log,
*f_helperlist, *f_nohelp, *f_helpername;
extern int f_disconnect, f_exceptions, f_helpers, f_loglevel, f_answertel,
f_pipes, f_fromhost;
extern char *progname;
extern char mydevname[];
extern int wstream;
struct wrthdr wt_head;
#ifdef TTYPERMS
int saveperms(void);
void setperms(char perm);
void resetperms(void);
#endif /*TTYPERMS*/
#endif /* LIB_COMMON_H */
orville-write-2.55/getutent.h 0100644 0000765 0000765 00000000634 07045473251 014410 0 ustar jan jan /* Header file for utmp reading routines */
#ifndef GETUTENT_H
#define GETUTENT_H
#ifdef HAVE_PATHS_H
# include
#endif
#ifndef _PATH_UTMP
# define _PATH_UTMP "/etc/utmp"
#endif
#ifndef HAVE_GETUTENT
int utmpname(const char *file);
void endutent(void);
void setutent(void);
struct utmp *getutent(void);
struct utmp *getutline(const struct utmp *ut);
#endif /*HAVE_GETUTENT*/
#endif /* GETUTENT_H */
orville-write-2.55/mesg.c 0100644 0000765 0000765 00000043663 10126436542 013504 0 ustar jan jan /* MESG command for Orville write
*
* This 'mesg' command is an extended version of the standard Unix 'mesg'
* command. It is designed to work with Orville write
*
* (C) Copyright, Sept 1985 - Jan Wolter
*
*/
#include "orville.h"
#include
#include
#include
#define TRUE 1
#define FALSE 0
char *mytty; /* my tty name in tty?? format */
long mypos; /* offset of my entry in wrttmp file */
struct wrttmp mywrt; /* my wrttmp entry */
struct utmp myutmp; /* A tmp buffer for reading utmp entries */
char silent= FALSE; /* generates no output if true */
int verbose= FALSE; /* generate whole table of output if true */
#define SMESG 0
#define SHELP 1
#define SRECO 2
#define SPREF 3
#define SMODE 4
#define SBELL 5
#define SEXCP 6 /* This must be last flag */
#define S_NUM 7
char *name[S_NUM]= {"mesg", "helper", "record", "preference",
"mode", "bells", "exceptions"};
char *vname[S_NUM]= {"messages", "helper flag", "record",
#ifdef WITH_TALK
"preference (write/tel/talk)",
#else
"preference (write/tel)",
#endif
"mode (line/character)",
"bells", "exceptions"};
/* Legal tag values for each type of setting. These must be listed in the
* order of the corresponding numerical codes. nmap lists all legal flags,
* smap lists only the flags that may be set by "mesg" and must have only
* truncated versions of the nmap strings. */
char *nmap[S_NUM]= {"yn","ynY","yna","wtkan","lca","yn","yn"};
char *smap[S_NUM]= {"yn","ynY","yn","wtkan","lca","yn","yn"};
char *vmap[S_NUM][4]= { {"yes","no","yes (exceptions)", "no (exceptions)"},
{"yes","no","always (Y)",NULL},
{"yes","no","all",NULL},
{NULL}, /* not used */
{"line","character","any",NULL},
{"yes","no",NULL,NULL},
{"yes","no",NULL,NULL}};
int report= SMESG; /* which of the above to put in return code */
void set_perms(char new_mesg, int open_up);
int report_status(void);
int get_status(int rep);
int find_me(void);
int may_help(void);
void do_disconnect(void);
int window_warning(int newmode);
char *myhomedir(void);
int maywriteme(char *user, int mode);
int main(int argc, char **argv)
{
int i,j;
char new[S_NUM] = {'x', 'x', 'x', 0x00, 'x', 'x', 'x'};
char disconnect= FALSE;
char open_up = FALSE;
int setting= SMESG;
int flip= 0;
int update;
char wassilent= FALSE;
int lastset= -1;
char flag;
/* Check if I have a valid tty */
if (!(fcntl(2,F_GETFL,0) & O_RDWR) || !isatty(2))
{
printf("%s: I/O stream 2 improperly redirected\n",argv[0]);
exit(2);
}
/* Find my tty line */
if (getdevtty()) exit(1);
mytty= mydevname+5;
progname= leafname(argv[0]);
/* Read configuration file */
readconfig(NULL);
/* Parse options */
for(i=1;i= '0' && flag <= '9')
{ if (setting != SPREF)
{
if (flag < '0' + strlen(smap[setting]))
flag= smap[setting][flag-'0'];
}
else
{
/* could be multi-digit number - add it up */
flag-= '0';
while (argv[i][j+1] >= '0' && argv[i][j+1] <= '9')
{
flag= 10*flag + argv[i][++j] - '0';
}
if (flag > TELPREF_ALL || flag < 0)
goto usage;
new[SPREF]= flag;
continue;
}
}
else
flag= argv[i][j];
switch (flag)
{
case '-':
if (j != 0) goto usage;
break;
case 'v':
verbose= TRUE;
break;
case 's':
if (setting != SMESG) goto usage;
wassilent= silent= TRUE;
break;
case 'm':
if (setting != SMESG) report= setting;
setting= SMODE;
break;
case 'b':
if (setting != SMESG) report= setting;
setting= SBELL;
break;
case 'r':
if (setting != SMESG) report= setting;
setting= SRECO;
break;
case 'p':
if (setting != SMESG) report= setting;
setting= SPREF;
flip= 0;
break;
case 'x':
if (setting != SMESG) report= setting;
setting= SPREF;
if (flip == 0) new[SPREF]= TELPREF_ALL;
flip= 1;
break;
case 'h':
if (!f_helpers)
{
printf("%s: Cannot use 'h' flag. Helpers not enabled "
"on this system.\n", progname);
exit(1);
}
if (setting != SMESG) report= setting;
setting= SHELP;
break;
case 'E':
case 'e':
if (!f_exceptions)
{
printf("%s: Cannot use '%c' flag. Exceptions not enabled "
"on this system.\n", progname, flag);
exit(1);
}
if (lastset != SMESG) goto usage;
new[SEXCP]= 'y';
break;
case 'Y':
if (setting == SMESG)
{
open_up= TRUE;
new[SMESG]= 'y';
lastset= SMESG;
break;
}
else if (setting != SHELP)
goto usage;
/* else drop through */
#ifdef WITH_TALK
case 'k':
#endif
case 'y':
case 'n':
case 'l':
case 'c':
case 'w':
case 't':
case 'a':
if (strchr(smap[setting],flag) == NULL) goto usage;
if (setting == SPREF)
{
if (flip)
{
switch (flag)
{
case 'w': new[SPREF]&= ~TELPREF_WRITE; break;
case 't': new[SPREF]&= ~TELPREF_TEL; break;
#ifdef WITH_TALK
case 'k': new[SPREF]&= ~TELPREF_TALK; break;
#endif
case 'n': new[SPREF]= TELPREF_ALL; break;
case 'a': goto usage;
}
}
else
{
switch (flag)
{
case 'w': new[SPREF]|= TELPREF_WRITE; break;
case 't': new[SPREF]|= TELPREF_TEL; break;
#ifdef WITH_TALK
case 'k': new[SPREF]|= TELPREF_TALK; break;
#endif
case 'a': new[SPREF]= TELPREF_ALL; break;
case 'n': goto usage;
}
}
}
else
new[setting]= flag;
lastset= setting;
setting= SMESG;
break;
case 'N':
lastset= SMESG;
case 'd':
if (setting != SMESG) goto usage;
disconnect= TRUE;
if (flag == 'N') new[SMESG]= 'n';
break;
#ifndef WITH_TALK
case 'k':
printf("%s: Talk permissions cannot be separately set "
"at this site\n",progname);
goto usage;
#endif
default:
goto usage;
}
}
/* If we changed message perms, but didn't set exceptions, turn them off */
if (new[SMESG] != 'x' && new[SEXCP] == 'x') new[SEXCP]= 'n';
if (setting != SMESG)
report= setting;
else if (report == SMESG)
report= ((lastset > SMESG) ? lastset : SMESG);
/* Open the wrttmp file and find us in it */
if (init_wstream(O_RDWR))
exit(-1);
find_me();
if ((new[SHELP] == 'y' || new[SHELP] == 'Y') && !may_help())
{
printf("You are not on the helper list.\n");
exit(1);
}
/* Update permissions/helperness/preferences/bells */
update= 0;
if (new[SMESG] != 'x')
{ set_perms(new[SMESG],open_up); update= 1; }
if (f_helpers && new[SHELP] != 'x')
{ mywrt.wrt_help= new[SHELP]; update= 1; }
if (f_exceptions && new[SEXCP] != 'x')
{ mywrt.wrt_except= new[SEXCP]; update= 1; }
if (new[SRECO] != 'x')
{ mywrt.wrt_record= new[SRECO]; update= 1; }
if (new[SMODE] != 'x')
{ mywrt.wrt_modepref= new[SMODE]; update= 1; }
if (new[SPREF] != 0x00 && !flip)
{ mywrt.wrt_telpref= new[SPREF]; update= 1; }
if (new[SPREF] != TELPREF_ALL && flip)
{ if (new[SPREF] == 0x00)
set_perms('n',0);
else
mywrt.wrt_telpref= new[SPREF];
update= 1;
}
if (new[SBELL] != 'x')
{ mywrt.wrt_bells= new[SBELL]; update= 1; }
/* Write out new settings */
if (update)
{
lseek(wstream,mypos,0);
write(wstream,&mywrt,sizeof(struct wrttmp));
silent= TRUE;
}
/* Disconnect existing connections */
if (disconnect)
{
if (f_disconnect)
do_disconnect();
else
printf("Disconnect option not enabled on this system\n");
silent= TRUE;
}
/* Close the utmp file */
endutent();
if (f_wrthist != NULL &&
!wassilent && (new[SMESG] == 'n' || new[SEXCP] == 'y'))
window_warning((new[SMESG]=='n')+2*(new[SEXCP]=='y'));
exit(report_status());
usage:
printf("usage: %s [-sv] [y|n", progname);
if (f_disconnect) printf("|d");
if (f_exceptions) printf("|ye|ne");
printf("|Y");
if (f_disconnect)
{
printf("|N");
if (f_exceptions)
printf("|NE");
}
printf("] ");
if (f_helpers) printf(" [-h[y|n|Y]]");
printf(" [-r[y|n]] [-m[l|c|a]] [-p[w|t|k|a]] [-x[w|t|k|n]] [-b[y|n]]\n");
exit(-1);
}
/* SET_PERMS: This sets the message permissions to "new_mesg" (which is
* either 'y' or 'n'. It throws the tty permissions wide open as well if
* "open_up" is true.
*/
void set_perms(char new_mesg, int open_up)
{
int mode;
/* Change the device permissions */
if (open_up)
mode= PERMS_OPEN;
#ifdef TTYPERMS
else if (new_mesg == 'y')
mode= PERMS_ON;
#endif /*TTYPERMS*/
else
mode= PERMS_OFF;
chmod(mydevname,mode);
/* Change the wrttmp permissions */
#ifndef TTYPERMS
mywrt.wrt_mesg= new_mesg;
#endif /*TTYPERMS*/
}
/* REPORT_PREF -- This prints a message reporting the perf setting, in
* verbose or non-verbose format. The appropriate numeric return code is
* returned.
*/
int report_pref(int verbose)
{
int val,n;
if (!silent)
{
if (verbose)
printf("%s: ",vname[SPREF]);
else
printf("%s is ",name[SPREF]);
}
val= mywrt.wrt_telpref;
if (val & TELPREF_OLD)
{
switch (val)
{
case 'w': val= TELPREF_WRITE; break;
case 't': val= TELPREF_TEL; break;
#ifdef WITH_TALK
case 'k': val= TELPREF_TALK; break;
#endif
case '-': case 'a': val= TELPREF_ALL; break;
}
}
if (!silent)
{
if (val == TELPREF_ALL)
{
fputs(verbose ? "all\n":"a\n" ,stdout);
return val;
}
n= 0;
if (val & TELPREF_WRITE)
{
fputs(verbose ? "write":"w" ,stdout);
n++;
}
if (val & TELPREF_TEL)
{
if (n > 0) putchar(',');
fputs(verbose ? "tel":"t" ,stdout);
n++;
}
#ifdef WITH_TALK
if (val & TELPREF_TALK)
{
if (n > 0) putchar(',');
fputs(verbose ? "talk":"k" ,stdout);
}
#endif
putchar('\n');
}
return val;
}
/* REPORT_STATUS -- This prints the current message permission settings and
* returns the status code (0 = yes; 1 = no). If silent is true, it omits
* the printing. If report is set to something other than SMESG it reports
* on that other setting. If verbose is true, it reports on all settings.
*/
int report_status()
{
int code,rc,i;
if (verbose)
{
for (i= 0; i < S_NUM; i++)
{
if (i == SEXCP) continue;
if (!f_helpers && i == SHELP) continue;
if (i == SPREF) {report_pref(1); continue; }
code= get_status(i);
printf("%s: %s\n",vname[i],
vmap[i][code] != NULL ? vmap[i][code] : "strange");
if (i == report) rc= code;
}
}
else
{
rc= get_status(report);
if (!silent)
{
if (f_exceptions && report == SMESG)
printf("%s is %c%s\n",name[report],nmap[report][rc%2],
rc > 1 ? "e" : "");
else if (report == SPREF)
report_pref(0);
else
printf("%s is %c\n",name[report],nmap[report][rc]);
}
}
return rc;
}
/* GET_STATUS -- Get current index code of given switch */
int get_status(int rep)
{
struct stat stb;
int code;
switch (rep)
{
case SMESG:
#ifdef TTYPERMS
/* Stat my tty */
if (stat(mydevname,&stb))
{
printf("%s: Error - can't stat %s\n",progname,mydevname);
exit(-1);
}
code= ((stb.st_mode & 0020)==0);
#else
code= strchr(nmap[SMESG],mywrt.wrt_mesg) - nmap[SMESG];
#endif /* TTYPERMS */
if (f_exceptions)
code+= 2 - 2*(strchr(nmap[SEXCP],mywrt.wrt_except) - nmap[SEXCP]);
break;
case SEXCP:
code= strchr(nmap[SEXCP],mywrt.wrt_except) - nmap[SEXCP];
break;
case SHELP:
code= strchr(nmap[SHELP],mywrt.wrt_help) - nmap[SHELP];
break;
case SRECO:
code= strchr(nmap[SRECO],mywrt.wrt_record) - nmap[SRECO];
break;
case SMODE:
code= strchr(nmap[SMODE],mywrt.wrt_modepref) - nmap[SMODE];
break;
case SBELL:
code= strchr(nmap[SBELL],mywrt.wrt_bells) - nmap[SBELL];
break;
}
return code;
}
/* DO_DISCONNECT -- This does the disconnect, by searching the wrttmp file for
* people who are writing you and sending a SIGTERM to each of the process
* numbers listed there. This whole approach is a bit shady.
*/
void do_disconnect()
{
struct utmp *ut; /* A tmp buffer for reading utmp entries */
struct wrttmp hiswrt; /* Someone's wrttmp entry */
int slot= 0;
/* Rewind utmp file */
setutent();
/* For each user who is writing me */
for (;;)
{
lseek(wstream, wrttmp_offset(slot++), 0);
if (read(wstream, &hiswrt, sizeof(struct wrttmp)) !=
sizeof(struct wrttmp))
break;
if (!strncmp(hiswrt.wrt_what, myutmp.ut_name, UT_NAMESIZE))
{
setutent();
/* Check apparant writer against utmp file */
while ((ut= getutent()) != NULL)
if (
#ifdef USER_PROCESS
ut->ut_type == USER_PROCESS &&
#endif
!strncmp(hiswrt.wrt_line, ut->ut_line, UT_LINESIZE))
{
/* Writer is for real: bonk him one */
kill(hiswrt.wrt_pid, SIGTERM);
break;
}
}
}
}
/* FIND_ME -- This finds my wrttmp entry and loads it into "mywrt".
*/
int find_me()
{
struct utmp *ut;
/* Find our entry in the Utmp file */
if ((ut= find_utmp(mytty)) == NULL || ut->ut_name[0] == '\0')
{
printf("%s: Unable to find your tty (%s) in utmp file\n",
progname,mytty);
exit(-1);
}
myutmp= *ut;
/* Find the entry in the wrttmp file */
find_wrttmp(mytty,myutmp.ut_time,&mywrt,&mypos);
}
/* MAY_HELP -- Check if the user's name is anywhere to be found in the
* f_helperlist file. If he is there, or the file doesn't exist at all, then
# he may designate himself as a helper.
*/
int may_help()
{
#define BUFSZ 80
FILE *hfp;
char buf[BUFSZ+1];
char myname[UT_NAMESIZE+2];
if (f_helperlist == NULL || (hfp= fopen(f_helperlist,"r")) == NULL)
return TRUE;
strncpy(myname,myutmp.ut_name,UT_NAMESIZE);
myname[UT_NAMESIZE]= '\0';
strcat(myname,"\n");
while (fgets(buf,BUFSZ,hfp) != NULL)
if (!strcmp(buf,myname))
{
fclose(hfp);
return TRUE;
}
fclose(hfp);
return FALSE;
}
/* WINDOW_WARNING - If there are people who can still write you under the
* four minute window rule, print a warning message.
*/
int window_warning(int newmode)
{
struct wrthist *hist;
struct wrttmp w;
struct utmp *u;
long writer, writee;
time_t now;
int n, foundsome= 0;
FILE *fp;
if (newmode == 0) return;
/* Compute my slot number from my offset */
if ((writer= (mypos - wt_head.hdr_size)/wt_head.tmp_size) > MAXSLOTS)
return;
if ((fp= fopen(f_wrthist,"r")) == NULL)
return;
fseek(fp,whindex(writer,0),0);
hist= (struct wrthist *)malloc(MAXSLOTS*sizeof(struct wrthist));
n= fread(hist,sizeof(struct wrthist),MAXSLOTS,fp);
fclose(fp);
now= time((time_t *)0);
for (writee= 0; writee < n; writee++)
{
if (hist[writee].tm > myutmp.ut_time &&
now - hist[writee].tm <= f_answertel)
{
/* Fetch "his" wrttmp entry - it may actually belong to a previous
* user on that line, so only the wrt_line field is really to be
* trusted.
*/
lseek(wstream,wrttmp_offset(writee),0);
if (read(wstream, &w, sizeof(struct wrttmp)) !=
sizeof(struct wrttmp))
continue;
/* Check times to ensure this is not from a later user */
if (hist[writee].tm < w.wrt_time)
continue;
/* Fetch his utmp entry, and confirm that the current user was
* already logged in there when we sent our last telegram there.
*/
if ((u= find_utmp(w.wrt_line)) == NULL || u->ut_name[0] == '\0' ||
hist[writee].tm < u->ut_time)
continue;
/* Check if due to exceptions he may write us anyway */
if (f_exceptions && newmode > 1 && maywriteme(u->ut_name, newmode))
continue;
if (!foundsome)
{
printf("Warning: Users to whom you recently sent messages may\n");
printf("still be able to write you for a few more minutes:\n");
foundsome= 1;
}
printf(" %-*.*s %-*.*s %4.1f more minutes\n",
UT_NAMESIZE, UT_NAMESIZE, u->ut_name,
UT_LINESIZE, UT_LINESIZE, u->ut_line,
(float)(f_answertel - now + hist[writee].tm)/60.0);
}
}
}
/* MYHOMEDIR - Return my home directory. Speed counts over reliability here.
* Return NULL if we can't find it.
*/
char *myhomedir()
{
char myname[UT_NAMESIZE+2];
struct passwd *pw;
char *dir, *getenv();
/* Try environment variable first */
if ((dir= getenv("HOME")) != NULL)
return dir;
/* If that don't work, try passwd file */
strncpy(myname,myutmp.ut_name,UT_NAMESIZE);
myname[UT_NAMESIZE]= '\0';
if ((pw= getpwnam(myname)) != NULL)
return pw->pw_dir;
/* If that don't work, give it up */
return NULL;
}
/* MAYWRITEME - can the named user write me? This checks exceptions. Does
* some caching so that multiple successive calls are efficient.
*/
int maywriteme(char *user, int mode)
{
static int oldmode= -1;
static char *list;
struct stat st;
char *dir,*fname, *p,*q;
FILE *fp;
int n, l, nl, sp;
if (mode < 2)
return (mode == 0);
if (mode != oldmode)
{
list= NULL;
oldmode= mode;
/* Open the appropriate exception file */
if ((dir= myhomedir()) == NULL)
return FALSE;
fname= (char *)malloc(strlen(dir)+15);
sprintf(fname,"%s/%s",dir, mode==2 ? ".nowrite" : ".yeswrite");
fp= fopen(fname,"r");
free(fname);
/* Load the file into memory */
if (fp != NULL && !fstat(fileno(fp),&st))
{
list= (char *)malloc(st.st_size+1);
n= fread(list,1,st.st_size,fp);
list[n]= '\0';
}
if (list != NULL)
{
/* Compress list into login names separated by single spaces */
nl= 1; sp= 1;
for (p= q= list; *p != '\0'; p++)
{
/* Skip lines starting with # */
if (nl && (*p == '#'))
{
p= strchr(p,'\n');
if (p == NULL) break;
}
nl= (*p == '\n');
if (strchr(" ,;:\t\n\r",*p))
{
if (!sp) *(q++)= ' ';
sp= 1;
}
else
{
sp= 0;
*(q++)= *p;
}
}
*q= '\0';
}
}
if (list != NULL)
{
/* Find length of user name */
for (l= 0; l < UT_NAMESIZE && user[l] != '\0'; l++)
;
/* Search compressed list for the name */
p= list;
for (;;)
{
if (!strncmp(p,user,l) && (p[l] == ' ' || p[l] == '\0'))
return (mode != 2);
if ((p= strchr(p,' ')) == NULL) break;
p++;
}
}
/* Not on list */
return (mode == 2);
}
orville-write-2.55/amin.c 0100644 0000765 0000765 00000017416 10126436536 013475 0 ustar jan jan /* AMIN.C
*
* Run a command, warning potential writers that you are in it.
*
* 8-24-86 Written by Jan Wolter
* 8-27-86 Added code to make it work with shell scripts
* 2-12-94 Fixed suspends.
* 11-30-95 Added -p
*/
#include "orville.h"
#include
#include
#include
#ifdef HAVE_SYS_WAIT_H
# include
#endif
#ifndef WEXITSTATUS
#define WEXITSTATUS(x) ((unsigned)(x) >> 8)
#endif
#ifndef WIFEXITED
#define WIFEXITED(x) (((x) & 255) == 0)
#endif
#include
extern int errno;
char *my_dir(void);
RETSIGTYPE susp(void);
void fix_modes(char *fullcmd);
void restore_modes(void);
int exec_cmd(int argc, char **argv);
struct wrttmp mywrt; /* My old wrttmp entry, to be restored at exit time */
struct wrttmp newwrt; /* Space to build temporary wrttmp entry */
long mypos= -1; /* offset of my entry in the wrttmp file */
char tmp_mesg= 's'; /* Temporary setting of mesg during write */
int fixed_modes= 0; /* Have we fixed the wrttmp/tty modes? */
int postpone= 0; /* Should telegrams be postponed? */
int exceptions= 0; /* Should we allow exceptions on message permissions */
int main(int argc, char **argv)
{
char cmdbuf[280]; /* Space to build full command path name */
char lmfile[200]; /* Space to store full path name of .lastmesg file */
FILE *lmfp= NULL;
int i,rc;
char *c;
progname= leafname(argv[0]);
readconfig(NULL);
for (i= 1; i \n",progname,
f_exceptions ? "e" : "");
exit(1);
}
/* MY_DIR - Return name of my home directory, or NULL if I can't find it.
*/
char *my_dir()
{
struct passwd *pwd;
char *r;
/* Try the environment variable first */
if ((r= getenv("HOME")) != NULL) return(r);
/* Try the password file */
setpwent();
pwd= getpwuid(getuid());
endpwent();
if (pwd != NULL)
return(pwd->pw_dir);
/* Give up */
return(NULL);
}
/* LOCATE_WRTTMP - find my entry in the wrttmp file.
*/
void locate_wrttmp(char *tty, struct wrttmp *wbuf, long *pos)
{
struct utmp *ut;
/* Find utmp entry */
if ((ut= find_utmp(tty)) == NULL || ut->ut_name[0] == '\0')
{
printf("%s: Can't find your tty (%s) in utmp\n",progname,tty);
exit(1);
}
find_wrttmp(tty, ut->ut_time, wbuf, pos);
}
/* FIX_MODES - modify wrttmp and tty permissions.
*/
void fix_modes(char *fullcmd)
{
char *mytty; /* my tty name in "tty##" format */
char *shortcmd; /* command without full pathname */
/* Find my tty line */
if (getdevtty()) exit(1);
mytty= mydevname+5;
/* Find my wrttmp entry */
locate_wrttmp(mytty,&mywrt,&mypos);
if (mypos < 0)
{
printf("%s: Error - unable to locate %s in %s\n",
progname, mytty, f_wrttmp);
exit(1);
}
/* Close utmp file */
endutent();
/* Figure out name of program being exec'ed */
if ((shortcmd= strrchr(fullcmd,'/')) == NULL)
shortcmd= fullcmd;
else
shortcmd++;
/* Fix my entry in wrttmp */
newwrt= mywrt;
newwrt.wrt_what[0]= '!';
strncpy(newwrt.wrt_what+1, shortcmd, UT_NAMESIZE-1);
#ifndef TTYPERMS
if (tmp_mesg != 's') newwrt.wrt_mesg= tmp_mesg;
#endif
if (tmp_mesg != 's')
newwrt.wrt_except= (f_exceptions && exceptions) ? 'y' : 'n';
if (postpone) newwrt.wrt_record= 'a';
lseek(wstream,mypos,0);
write(wstream,&newwrt,sizeof(struct wrttmp));
#ifdef TTYPERMS
/* Fix my tty permissions */
if (tmp_mesg != 's')
{
if (saveperms()) exit(1);
setperms(tmp_mesg);
}
#endif /*TTYPERMS*/
fixed_modes= 1;
}
/* RESTORE_MODES - Restore original modes.
*/
void restore_modes()
{
/* Restore old (or default) wrttmp entry */
lseek(wstream,mypos,0);
write(wstream,&mywrt,sizeof(struct wrttmp));
close(wstream);
#ifdef TTYPERMS
if (tmp_mesg != 's') resetperms();
#endif /*TTYPERMS*/
}
/* EXEC_CMD - Run the command as a child process
*/
int exec_cmd(int argc, char **argv)
{
int cpid,wpid; /* Child pid and pid returned by wait */
char **shargv; /* Arguements for running things with shell */
int status; /* Child's return status */
int i;
if ((cpid= fork()) == 0)
{
/* Child process */
/* Use default interupts */
signal(SIGINT,SIG_DFL);
signal(SIGQUIT,SIG_DFL);
signal(SIGTERM,SIG_DFL);
signal(SIGHUP,SIG_DFL);
#ifdef SIGTSTP
signal(SIGTSTP,SIG_DFL);
#endif /*SIGTSTP*/
/* Close open file descriptors */
/* close(wstream); /* Don't need this, since set close-on-exec */
endutent(); /* Might or might not need this */
execvp(argv[0],argv);
/* If wasn't executable, try running under a shell */
if (errno == ENOEXEC)
{
shargv= (char **)malloc((argc+3)*sizeof(char *));
shargv[0]= "sh";
shargv[1]= "-c";
for (i= 0; i < argc; i++)
shargv[i+2]= argv[i];
shargv[i+2]= NULL;
execv("/bin/sh",shargv);
}
printf("%s: command not found\n",argv[0]);
exit(1);
}
/* Parent Process waits for child to exit */
while ((wpid= wait(&status)) != cpid && wpid != -1)
;
return (WIFEXITED(status) ? WEXITSTATUS(status) : -2);
}
/* SUSP -- Suspend the process. Restore wrttmp entries first, since we can't
* assume that stopped processes will be restarted in the reverse order in
* which they were stopped.
*/
#ifdef SIGTSTP
RETSIGTYPE susp()
{
int mask;
/* Disable further signals */
mask= sigblock(sigmask(SIGTSTP));
/* Restore modes and make wrttmp look like we exited */
if (fixed_modes)
{
lseek(wstream,mypos,0);
write(wstream,&mywrt,sizeof(struct wrttmp));
#ifdef TTYPERMS
if (tmp_mesg != 's') resetperms();
#endif /*TTYPERMS*/
fixed_modes=0;
}
signal(SIGTSTP,SIG_DFL);
sigsetmask(0);
kill(getpid(),SIGTSTP);
/* STOP HERE */
sigsetmask(mask);
signal(SIGTSTP,(void (*)())susp);
/* Reinstate wrttmp entry */
lseek(wstream,mypos,0);
write(wstream,&newwrt,sizeof(struct wrttmp));
#ifdef TTYPERMS
if (tmp_mesg != 's')
{
if (saveperms()) exit(1);
setperms(tmp_mesg);
}
#endif /*TTYPERMS*/
}
#endif /*SIGTSTP*/
orville-write-2.55/huh.c 0100644 0000765 0000765 00000004613 07665675304 013344 0 ustar jan jan #include "write.h"
#include
#include
int keep= 0, silent= 0;
/* MY_DIR - Return name of my home directory, or NULL if I can't find it.
*/
char *my_dir()
{
char *r;
struct passwd *pwd;
/* Try the environment variable first */
if ((r= getenv("HOME")) != NULL) return r;
/* Try the password file */
setpwent();
pwd= getpwuid(getuid());
endpwent();
if (pwd != NULL) return pwd->pw_dir;
/* Give up */
return NULL;
}
/* RECORD_ON -- return true if the user has his record flag on. We don't
* really care, but we want to tell him about it if this is the reason he
* hasn't any messages.
*/
int record_on()
{
struct utmp *ut;
struct wrttmp wt;
char *tty;
long pos;
/* Open the utmp file */
setutent();
/* Open the wrttmp file */
if (init_wstream(O_RDONLY)) return 1;
/* Get tty name */
if (getdevtty()) exit(1);
tty= mydevname+5;
/* Find our entry in the utmp file */
if ((ut= find_utmp(tty)) == NULL || ut->ut_name[0] == '\0') return 1;
/* Find the entry in the wrttmp file */
find_wrttmp(tty, ut->ut_time, &wt, &pos);
/* Close utmp file */
endutent();
return (wt.wrt_record != 'n');
}
int main(int argc, char **argv)
{
char fname[200];
char *dir;
FILE *fp;
int ch;
int i,j;
struct stat st;
progname= leafname(argv[0]);
readconfig(NULL);
for (i= 1; i < argc; i++)
{
if (argv[i][0] == '-')
for (j= 1; argv[i][j] != '\0'; j++)
switch(argv[i][j])
{
case 'k':
keep= 1;
break;
case 's':
silent= 1;
default:
goto usage;
}
else
goto usage;
}
if ((dir= my_dir()) == NULL)
{
fprintf(stderr,"%s: cannot find your home directory\n",progname);
exit(1);
}
sprintf(fname,"%.180s/.lastmesg",dir);
if ((fp= fopen(fname,"r")) == NULL)
{
printf("No recorded messages%s.\n", (silent || record_on()) ? "":
" (do \042mesg -r y\042 to record future messages)");
exit(0);
}
if (fstat(fileno(fp), &st) || st.st_uid != getuid())
{
printf("Incorrect ownership of %s\n",fname);
exit(1);
}
/* Unlink the file -- do it now to minimize conflicts with incoming
* messages.
*/
if (!keep) unlink(fname);
/* Display the file */
if (!silent)
while ((ch= getc(fp)) != EOF)
{
if (ch != '\007') putchar(ch);
}
exit(0);
usage: fprintf(stderr,"usage: %s [-ks]\n", progname);
exit(1);
}
orville-write-2.55/amin.1 0100644 0000765 0000765 00000003465 07044101626 013404 0 ustar jan jan .\" @(#)amin.1 2.41 (Wolter) 1/27/2000
.\"
.TH AMIN 1 "July 1, 1991"
.AT 3
.SH NAME
amin \- notify writers that you are busy
.SH SYNOPSIS
.B amin
[-ynesp] command [args...]
.SH DESCRIPTION
.I Amin
is used when you don't want to be written while running a command.
It runs the command given normally. If your message permissions
(see
.IR mesg (1))
are off, it does nothing much else.
If your messages are on, people writing you with
.IR write (1)
will be warned that you are running that command and
will be given the opportunity to change their minds about writing you.
.PP
The
.B -n
option may be used to turn your messages entirely off for the duration
of the execution of command.
People writing you will get "Permission denied".
The
.B -y
option turns your message permissions on for the duration of
the execution of the command.
The
.B -e
may be used after either
.B -n
or
.B -y
to indicate that the logins listed in the
.I .yeswrite
or the
.I .nowrite
files respectively are exceptions to the message permissions set.
The default is
.B -s
which leaves your message permissions in their original state.
In any case, after the command is complete,
your permissions will be restored to the original state.
.PP
The
.B -p
flag causes all telegrams sent to you while the command is running to be saved.
They are displayed as soon as the command is complete.
If used with the
.B -n
flag, writes are refused, but telegrams are still saved.
.PP
If you have designated yourself as a helper, you will still be marked on
the
.IR finger (1)
output as a helper while you are running
.I amin
but people doing ``write help'' will not be connected to you,
even if you have the helper flag set to ``Y''.
.SH AUTHOR
Jan Wolter
.SH FILES
/etc/wrttmp to find message permissions
.br
/etc/utmp to find user
.SH "SEE ALSO"
mesg(1), finger(1), write(1), huh(1).
orville-write-2.55/write.1 0100644 0000765 0000765 00000027566 07665700751 013637 0 ustar jan jan .\" @(#)write.1 2.41
.\"
.TH WRITE 1 "Jan 20, 2000"
.AT 3
.SH NAME
write \- write to another user
.SH SYNOPSIS
.B write
[-ctynsprfSv] [ user [ tty ] ]
.br
.B jot
[-ltynsprfSv] [ user [ tty ] ]
.br
.B tel
[-clynsprfSv] user [ tty ] [message...]
.SH DESCRIPTION
Note: This is "Orville write", an enhanced version of the standard Unix
.I write
program.
.I Write
copies lines from your terminal to that of
another user. When first called, it sends the message:
.PP
Message from your-logname your-tty ...
.PP
The recipient of the message should write back at this point.
Communication continues until an end of file is read from the terminal
or an interrupt is sent.
At that point,
.I write
writes "EOF (your-logname)" on the other terminal and exits.
.PP
The following protocol is strongly suggested for using
.IR write :
when you first write to another user,
wait for him or her to write back before starting to type your message.
Each party should end each message with a distinctive signal
(\fBo\fR for
``over'' is conventional), indicating that the other may reply;
.B oo
for ``over and out'' is suggested when conversation is to be terminated.
Avoid typing when it is the other person's turn, as your text will get
all garbled with theirs.
Anyway, it's rude.
.PP
The
.I jot
command is a variation of
.I write
which normally
sends each character to the other user as you type it instead of
waiting for you to finish a line before sending anything as write does.
.PP
The
.I tel
command sends one line ``telegrams'' and then immediately disconnects.
The message may be given on the command lines (in which case it is
usually best to quote it).
If you don't put a message on the command line, you will be prompted for it.
This is usually the preferable way to invoke
.I tel.
.PP
All three commands are actually the same program, and share much of the same
behavior.
.PP
Permission to write may be denied or granted by use of the
.IR mesg (1)
command.
Your write permissions upon login are installation dependent.
If you write a person who has permissions on,
but is currently writing someone else,
you will be warned of the fact and be given
a chance to cancel your write request before interupting
the other conversation.
If you write a person who is running a command under
.IR amin (1)
you will be warned similarly.
.PP
You can always send messages to people who are currently writing to you,
even if there message permissions are off.
If you have sent a person a
.I tel
message, then that person can write or telegram to you for the next 4 minutes,
even if your message permissions are off.
This means that you won't be sitting around wondering why someone won't
reply, just because you've forgotten to turn your permissions on.
It also means that if you don't want someone to be able to talk to you, then
you shouldn't talk to them.
Root may write anyone.
.PP
If you invoke the
.I write
or
.I jot
command with no user name,
they will write to whatever user is currently writing you.
If no one is writing you, an error message is printed.
.PP
If you invoke the
.IR write ,
.IR jot ,
or
.I tel
command with the user name '.',
they will write again to whoever you wrote to last.
If you haven't written to anyone in this login session,
an error message is printed.
This is especially useful when you are exchanging a series of messages back
and forth with
.IR tel .
.PP
If you want to write to a user who is logged in more than once,
the tty argument may be used to indicate the appropriate terminal.
If the tty argument is not given,
the terminal from which you are being written will be written to,
if there is one. If not, one of the lines you have write permission to
will be chosen.
If the tty argument is given, the user name can be given as "-", in which
case it will write to whomever is on that tty, if anyone is.
.PP
On some systems there may be users designated as ``helpers''.
If your system has helpers, then doing ``write help'' will write to some
helper who is not busy.
If more than one helper is available, one is
selected at random to distribute the workload.
Helpers designate themselves with the
.IR mesg (1)
command.
They are considered busy if they are writing someone else, or if they
are running a command under the
.IR amin (1)
program.
.PP
If the character ! , | , or & is found at the beginning of a line,
.I write
calls the shell to execute the rest of the line as a unix command.
If the command began with a ! the output of the command
will be sent only to your terminal.
If it began with a |, output will be sent only to the other person's terminal.
If it began with a & each of you will recieve a copy of the output.
Note that
.I write
expands all strange control characters before sending them
to the other person's terminal,
but does not do so for characters echoed back to your terminal.
.PP
.I Write
provides several command line options.
Actually, the only difference between
.IR write ,
.IR jot ,
and
.I tel
is what default values they have for these options:
.TP
.B \-c
Send each character as it is typed. Actually, it will not begin
doing so until after the other party has replied. Also, if you type
a line starting with a ")" then the rest of the current line will be held
until you hit return and the sent (minus the ")").
When
this option used, typing a control-R
will reprint the text of the line you are currently typing,
and control-W will erase the last word you typed,
even if your unix system doesn't usually support these.
In the
.I jot
command this is the default.
.TP
.B \-l
Send no characters until a full line has been entered.
In the
.I write
command this is the default.
.TP
.B \-n
During the duration of this conversation,
temporarily turn off your message permissions,
so as not to allow people other than the
person being writen to write you.
.TP
.B \-y
During the duration of this conversation, temporarily turn on your message
permissions,
allowing other people to write you after warning them that you are
writing someone else.
.TP
.B \-p
Postpone the receipt of telegrams
during the duration of the conversation.
All telegram received during the conversation
will be saved in your .lastmesg file,
and will be displayed when you are finished.
The
.IR huh (1)
command can be used in a shell escape to check saved messages without leaving
.IR write .
.TP
.B \-s
During the duration of this conversation,
leave your write permissions unchanged.
This normally the default.
.TP
.B \-r
This causes
.I write
to prompt for the root passwd.
If it is given correctly, you will be able to write anyone, no matter how
his message permissions are set, amd you can override his preference for
.I write
or
.IR tel .
.TP
.B \-f
Disallow piping input through
.I write
and disable the '&' and '|' shell escapes.
This is mostly meant to be used on 'options' commands in the orville.conf file.
It has been mostly obsoleted by the 'pipes' configuration command.
.TP
.B \-t
Sends a one line message (called a telegram) and then disconnects immediately.
The text of the message may be given on the command line, or, if it isn't,
you will be prompted for it.
Though write will attempt to blank out messages given on the command line
so they cannot be seen by users running
.IR w (1)
or
.IR ps (1),
this will not always work, so secret messages should not be placed on the
command line.
This is the default in the
.I tel
command.
.TP
.B \-S
Normally if you send a telegram to someone who has indicated a preference
for writes, you get asked if you want to switch to writing, and vice versa.
The -S flag suppresses this question, and just makes it quietly fail
(unless you are root, in which case it quietly succeeds).
.TP
.B \-v
print the version number.
.PP
The options selected by the writer may in some cases be overridden by the
recipient.
You can set your preferences for writes versus telegrams,
and for line mode versus character mode with the
.IR mesg (1)
command.
If the recipient has set write/telegram
preferences, you will be asked if you want to use the other if you write
him the wrong way.
If you invoke
.I Write
with a
.B \-S
flag, then you will not be asked if you want to switch.
Only root can actually override the recipient's preferences.
For regular users, if you decline to switch, the command fails.
.PP
If the recipient has set character/line mode preferences,
a message will be printed and
you will be forced into his or her prefered mode.
.SH CONFIGURATION
The
.I orville.conf
file contains configuration information for Orville write and the associated
utilities. Lines starting with '#' and blank lines are ignored. Other lines
contain the commands listed below:
.IP "answertel " 1i
Normally you can send telegrams to a person for four minutes (240 seconds)
after they sent you a telegram, even if their message permissions are off.
This command can be used to set size of that window to other values.
.IP "disconnect [y|n]" 1i
If disconnect is enabled the 'mesg d' and 'mesg N' commands
can be used by the writee
to disconnect everyone currently writing them. (See
.IR mesg (1)).
It is enabled by default.
.IP "exceptions [y|n]" 1i
If exceptions are enabled the 'mesg ye' and 'mesg ne' commandsa
can be used to limit which particular users can and cannot write you (See
.IR mesg (1)).
It is enabled by default.
.IP "fromhost [y|n]" 1i
If this flag is set, then message announcement banners will include the
hostname of the sender's machine (and the reciever's since write does
not allow interhost communications).
It is disabled by default.
.IP "helperlist " 1i
If this flag is set, then only people whose logins appear in the given file
may be helpers. Otherwise, anyone may be.
It is disabled by default.
.IP "helpername " 1i
By default you get help by doing 'write help'. If you want to use some
keyword other than 'help', use this command to define it.
.IP "helpers [y|n]" 1i
Can people designate themselves to be helpers, and should 'write help'
work? By default, no.
.IP "log " 1i
What file should logging be done in? If not defined, or if it is defined
and the file does not exist, then no logging will be done.
.IP "loglevel " 1i
How much logging should be done? Level 0 means none. Level 1 means only
log help requests (with information about whether they succeeded or not).
Level 2 means logging a one-line description of each write connection made.
Of course, no logging is done if 'log' is not defined or does not exist.
No content of any write conversation is ever logged.
The default is 1.
.IP "nohelp " 1i
If someone does 'write help', but no helpers are found, this file is displayed.
Normally it has information on other places to get help.
If not defined, nothing is printed.
.IP "pipes [y|n]" 1i
If turned off, this disallows piping data through write, so you can't do
'cat /etc/termcap | write joe'. It also disables the '|' and '&' shell
escapes. This may be necessary if many users are using write to annoy other
users by sending large chunks of data.
It defaults on.
.IP "novicehelp " 1i
If the environment variable NOVICE is defined, then print the contents of this
file before running write. If not defined, nothing is printed.
.IP "options -..." 1i
Set default options for different links to the write program. For example,
if you have the line 'options jot -c' and you make a link to the write program
named 'jot', then jot will default to character mode instead of line mode.
If command-name is '*', then all links (even ones created by users) get that
option.
.IP "wrthist " 1i
This is the full pathname of the 'wrthist' file which maintains information
about user's recent messages. It is used to limit telegram flooding attacks,
and allow replies to telegrams during the four minute window.
By default it is in the same directory as the
'orville.conf' file.
.IP "wrttmp " 1i
This is the full pathname of the 'wrttmp' file which maintains information
about user's current state. By default it is in the same directory as the
'orville.conf' file.
.SH AUTHOR
Jan Wolter
.SH "SEE ALSO"
mail(1), mesg(1), who(1), huh(1), finger(1), amin(1), helpers(1).
orville-write-2.55/mesg.1 0100644 0000765 0000765 00000016016 07044176376 013425 0 ustar jan jan .\" @(#)mesg.1 2.41
.\"
.TH MESG 1 "Jan 20, 2000"
.AT 3
.SH NAME
mesg \- permit or deny messages
.SH SYNOPSIS
.B mesg
[-s] [-v] [y|n|ye|ne|Y|N|NE] [d] [-p[w|t|k|a]] [-x[w|t|k|n]] [-m[l|c|a]] [-h[Y|y|n]] [-r[y|n]] [-b[y|n]]
.SH DESCRIPTION
This is the "Orville write" verison of the standard Unix
.I mesg
command.
.PP
.I Mesg
with argument
.B n
forbids messages via
.IR write (1),
.IR jot (1),
.IR tel (1),
and
.IR talk (1)
by revoking non-user
write permission on the user's terminal.
.I Mesg
with argument
.B y
reinstates permission.
All by itself,
.I mesg
reports the current state without changing it.
.PP
The
.B ne
and
.B ye
settings mean ``no with exceptions'' and ``yes with exceptions'' respectively.
If
.B ne
is set, and there is file named
.I .yeswrite
in your home directory,
then the users whose logins are listed there may still write you.
If
.B ye
is set, and there is a file named
.I .nowrite
in your home directory,
then the users whose logins are listed there may not write you.
These files have no effect if the permissions are set to
.B n
or
.BR y .
The
.I .nowrite
and
.I .yeswrite
files do not need to be permitted to anyone else,
and almost any plausible format will be understood
(listing one login name per line is a good default).
Lines may be commented out with a # sign in the first column.
.PP
The upper case
.B Y
and
.B N
do all that the lower case ones do, but may have some additional affects
depending on the installation.
.PP
The
.B N
argument, if enabled, will attempt to disconnect any write sessions currently
directed at your tty.
This is meant to allow users to slam the door on unwelcome writers.
Note that a simple ``mesg n'' will not stop anyone who is already writing
you from continuing to do so, it only prevents new connections from being
made.
The
.B NE
setting also causes a disconnect, but turns your settings to
.B ne
instead of
.BR n .
The
.B d
argument causes a disconnect, just like ``mesg N'', but does not change
your message permissions.
.PP
Normally
.I mesg
always depermits your tty device, so you can only be written through
.I write
and similar programs.
This prevents arbitrary stuff from being redirected to your tty.
When you do ``mesg Y''
your tty is write permitted to others.
This is rarely necessary or desirable.
.PP
.I Mesg
can also be used to set other switches that affect Orville
.IR write (1).
The
.B -p
flag lets you set preferences to
(w) write, (t) telegrams, (k) talk, or (a) any.
The default is ``any.''
If you set a preference to write,
then people will not be able to send telegrams or talk requests to you.
If they try to send telegrams, they will be asked if they want to write
you instead.
Similarly if you prefer telegrams, people will not be able to write or talk to
you, and if you prefer talk, people will not be able to write or tel you.
You can designate two preferences, like ``mesg -pt -pw'' to allow people to
write or telegram you, but not make talk requests to you.
Alternately, you can use the
.B -x
flag to block particular programs.
Doing ``mesg -xk'' blocks only the talk program, and is equivalent to
``mesg -pt -pw''.
Similarly the ``-xn'' flag excludes no programs and is equivalent to ``-pa''.
Trying to block all programs just turns you permissions off.
.PP
The
.B -m
flag lets you set modes to
(l) line, (c) character, or (a) any.
The default is ``any.''
If you set a mode, then all writes to you will be done in that mode.
If you leave it as ``any,''
the choice is left to the writer.
This will not affect connections already in progress, only future ones.
.PP
The
.B -r
flag lets you turn on or off the recording to telegrams sent to you.
If it is enabled, everytime you are sent a telegram (or a write with
input taken from a file), the text of the messages is saved in a file
named .lastmesg in your home directory. This allows you to redisplay
the last message sent to you using the
.IR huh (1)
command.
If a screen clear ate a telegram message before you had time to read it,
then the
.I huh
command lets you see it again.
Note that only the last message sent is stored.
The file is permitted to be readable to you only.
.PP
The
.B -b
flag lets you tell the
.I write
and
.I talk
programs whether or not to beep
when a person writes you or sends you a telegram. The default is to beep.
.PP
The
.B -h
flag lets you turn on or off your helper status.
People who designate themselves as helpers are announcing their
willingness to help out lost users.
Their accounts will be marked on the
output of the
.IR finger (1)
command, and if anyone does a
.I write
or
.IR jot (1)
to ``help'' they automatically get connected to someone who has a help
flag set.
Normally, turning your permissions off also turns your helper-status off,
but if you set the
.I -h
flag to
.IR Y ,
then you will remain a helper even when your message permissions are off.
This means you can receive help requests, but not normal messages.
.PP
On some systems there is a restricted list of users who may be helpers.
This is usually kept in the file /etc/helpers, one login name per line.
If such a file exists then you will have to get the operators to add your
name to it to be able to designate yourself as a helper.
.PP
If no new settings are given to
.IR mesg ,
then it just reports on the current settings.
Normally it prints the message permissions, but if a
.BR -h ,
.BR -p ,
.BR -r ,
or
.B -m
flag was given without a new value after it, then the current status of
that switch will be printed instead.
If you use the
.B -s
flag, then this output will be suppressed.
The command still reports the status of the selected switch with its numeric
return code.
.PP
If you use the
.B -v
flag, all switch settings will be reported in a verbose mode.
.PP
The numeric values returned as return codes
(see below) can also be used to set switches.
Thus ``mesg 0 -m2'' sets permissions on, and the mode to any.
This makes it easy for shell scripts to restore settings that were stored
previously.
.PP
The argument syntax is actually a lot looser than mentioned above.
The dashes before options may be omitted,
Spaces may be added or omitted anywhere in the argument list.
.SH FILES
/dev/tty*
.br
/etc/wrttmp
.br
/etc/helpers
.SH "SEE ALSO"
write(1), amin(1), finger(1), huh(1), helpers(1), talk(1)
.SH DIAGNOSTICS
Exit status is -1 on an error.
Otherwise a code is returned reporting the status of one of the settings.
If the arguments included
.BR -h ,
.BR -p ,
or
.B -m
flags without a new value after it, then the last of these listed will be
reported.
Otherwise, if any options were set, the last of those listed in the argument
list will be reported.
And if nothing was set, then message permissions are reported.
.PP
When message permissions, record settings, or helper settings are reported,
0 indicates 'y', and 1 indicates 'n'.
When preferences are reported,
1 indicates 'w', 2 indicates 't', and 4 indicates 'k', and any combinations
are returned as sums of these values.
When modes are reported,
0 indicates 'l', 1 indicates 'c', and 2 indicates 'a'.
.SH BUGS
Turning off 'talk' permissions will only work if you have a talkd which has
been modified to understand Orville write's permission.
orville-write-2.55/huh.1 0100644 0000765 0000765 00000001615 07044101660 013235 0 ustar jan jan .\" @(#)huh.1 2.41
.\"
.TH HUH 1 "Jan 20, 2000"
.AT 3
.SH NAME
huh \- redisplay last telegram received.
.SH SYNOPSIS
.B huh
[-sk]
.SH DESCRIPTION
.I Huh
reprints the last telegram that was sent to you.
It is intended for use when telegrams get garbled on your screen.
.I Huh
will only work if you had the ``record'' flag
turned on when the telegram was received.
This flag can be turned on with the
.IR mesg (1)
command.
Normally,
.I huh
will delete each message immediately after displaying it.
If the
.B -k
flag is given, the message is non deleted, and the next
.I huh
command will display it again.
On the other hand, the
.B -s
flag suppresses the display of the message, so it will just be deleted.
Normally, only the last message is retained,
except when
.IR amin (1)
is run with the
.B -p
flag.
.SH AUTHOR
Jan Wolter
.SH FILES
~/.lastmesg
.br
/etc/wrttmp
.SH "SEE ALSO"
mesg(1), write(1), amin(1)
orville-write-2.55/wrttab 0100644 0000765 0000765 00000000040 06673762531 013625 0 ustar jan jan *
chat -c
tel -ct
telegram -ct
orville-write-2.55/wt.c 0100644 0000765 0000765 00000003376 07044175042 013200 0 ustar jan jan /* Dump WRTTMP file - This is a debugging command which prints out the current
* contents of the wrttmp file in a human-readable format. Since it is rather
* cryptic, I wouldn't recommend installing it for general use.
*/
#include "orville.h"
/* Return a pointer to a string of n dashes. No more than MAXDASH allowed. */
char *dashes(n)
int n;
{
#define MAXDASH 30
static char *d= "------------------------------"; /* Exactly MAXDASH -'s */
return(n<=MAXDASH ? d+(MAXDASH-n) : d);
}
main(int argc, char **argv)
{
FILE *fp;
struct wrttmp w;
struct wrthdr wt_head;
int slot= 0;
long x;
progname= leafname(argv[0]);
readconfig(NULL);
if ((fp= fopen(f_wrttmp,"r")) == NULL)
{
printf("cannot open %s\n",f_wrttmp);
exit(1);
}
if (!fread(&wt_head,sizeof(struct wrthdr),1,fp))
{
printf("%s exists, but has no header\n",f_wrttmp);
exit(1);
}
printf("HEAD SIZE = %ld ENTRY SIZE = %ld\n\n",
wt_head.hdr_size, wt_head.tmp_size);
printf("--line%s --what%s --last%s * E P M H R B --pid-- ---login time---\n",
dashes(UT_LINESIZE-6),
dashes(UT_NAMESIZE-6),
dashes(UT_NAMESIZE-6));
for (;;)
{
x= wrttmp_offset(slot++);
fseek(fp,x,0);
if (!fread(&w,sizeof(struct wrttmp),1,fp))
break;
printf("%-*.*s %-*.*s %-*.*s %c %c %2d %c %c %c %c %7d %15.15s\n",
UT_LINESIZE,UT_LINESIZE,w.wrt_line,
UT_NAMESIZE,UT_NAMESIZE,w.wrt_what,
UT_NAMESIZE,UT_NAMESIZE,w.wrt_last,
#ifndef TTYPERMS
isprint(w.wrt_mesg) ? w.wrt_mesg : '#',
#else
' ',
#endif
isprint(w.wrt_except) ? w.wrt_except : '#',
w.wrt_telpref,
isprint(w.wrt_modepref) ? w.wrt_modepref : '#',
isprint(w.wrt_help) ? w.wrt_help : '#',
isprint(w.wrt_modepref) ? w.wrt_record : '#',
isprint(w.wrt_bells) ? w.wrt_bells : '#',
w.wrt_pid,
ctime(&w.wrt_time)+4);
}
}
orville-write-2.55/helpers.c 0100644 0000765 0000765 00000007326 07054022050 014176 0 ustar jan jan /* HELPERS - List or count of current helpers.
*
* (C) Copyright, Nov 1995 - Jan Wolter
*/
#include "orville.h"
#include
/* Structure for list of ttys with helpers on them. */
struct hlp {
time_t time; /* login time from wrttmp file */
char line[UT_LINESIZE]; /* ttyline occupied by a helper */
int busy; /* is he busy? */
struct hlp *next; /* next helper */
} *list= NULL;
/* FINDLIST - search the list for the named tty. If found, remove it from the
* list, and return a pointer to it. If not found, return NULL.
*/
struct hlp *findlist(char *tty)
{
struct hlp *curr, *prev;
for (curr= list, prev= NULL; curr != NULL; prev= curr,curr= prev->next)
{
if (!strncmp(tty, curr->line, UT_LINESIZE))
{
if (prev == NULL)
list= curr->next;
else
prev->next= curr->next;
return(curr);
}
}
return(NULL);
}
/* PERMS_ON: Return true if permissions for the user whose wrttmp entry is
* passed in are on. This doesn't test the exception files.
*/
int perms_on(struct wrttmp *w)
{
struct stat st;
char devname[UT_LINESIZE+7];
#ifdef TTYPERMS
#define MASK 022
#else
#define MASK 002
if (w->wrt_mesg != 'n')
return(1);
#endif /*TTYPERMS*/
/* Is his tty physically writable? */
sprintf(devname,"/dev/%.*s",UT_LINESIZE,w->wrt_line);
if (stat(devname,&st))
return(0);
return ((st.st_mode & MASK) != 0);
}
main(int argc, char **argv)
{
FILE *fp;
struct wrttmp w;
struct wrthdr wt_head;
struct utmp *u;
struct hlp *tmp;
int i, j;
int slot= 0;
int count= 0;
int freeonly= 0;
int listthem= 1;
progname= leafname(argv[0]);
readconfig(NULL);
/* Parse command line options */
for (i= 1; i < argc; i++)
{
if (argv[i][0] != '-' || argv[i][1] == '\0')
goto usage;
for (j= 1; argv[i][j] != '\0'; j++)
switch(argv[i][j])
{
case 'f':
freeonly= 1;
break;
case 'l':
listthem= 1;
break;
case 'n':
listthem= 0;
break;
default:
goto usage;
}
}
/* Open wrttmp file */
if ((fp= fopen(f_wrttmp,"r")) == NULL)
{
printf("cannot open %s\n", f_wrttmp);
exit(1);
}
/* Scan through wrttmp file, looking for help */
if (fread(&wt_head,sizeof(struct wrthdr),1,fp))
{
for (;;)
{
fseek(fp,wrttmp_offset(slot++),0);
if (!fread(&w,sizeof(struct wrttmp),1,fp))
break;
/* skip obvious non-helpers */
if ((w.wrt_help != 'y' && w.wrt_help != 'Y') ||
(freeonly && w.wrt_what[0] != '\0'))
continue;
/* check his permissions */
if (w.wrt_help != 'Y' && !perms_on(&w))
continue;
/* Found an apparent helper - save in linked list */
tmp= (struct hlp *)malloc(sizeof(struct hlp));
strncpy(tmp->line,w.wrt_line,UT_LINESIZE);
tmp->time= w.wrt_time;
tmp->busy= (w.wrt_what[0] != '\0');
tmp->next= list;
list= tmp;
}
}
fclose(fp);
/* Scan through utmp file, looking for ttys on our list */
if (list != NULL)
{
/* Do the scan */
while ((u= getutent()) != NULL)
{
#ifdef USER_PROCESS
if (u->ut_type != USER_PROCESS)
continue;
#endif
if ((tmp= findlist(u->ut_line)) != NULL)
{
/* If the time stamps don't match, this isn't a real helper */
if (u->ut_time == tmp->time)
{
/* Found a real helper -- count and print */
count++;
if (listthem)
printf("%-*.*s %-*.*s%s\n",
UT_NAMESIZE, UT_NAMESIZE, u->ut_name,
UT_LINESIZE, UT_LINESIZE, u->ut_line,
tmp->busy ? " [busy]" : "");
}
free(tmp);
if (list == NULL) break;
}
}
endutent();
}
if (!listthem)
printf("%d\n",count);
else if (count == 0)
printf("NONE\n");
exit(0);
usage:
printf("usage: %s [-fln]\n",argv[0]);
exit(1);
}
orville-write-2.55/helpers.1 0100644 0000765 0000765 00000001333 07044101647 014115 0 ustar jan jan .\" @(#)helpers.1 2.41
.\"
.TH HUH 1 "Jan 20, 2000"
.AT 3
.SH NAME
helpers \- list or count helpers currently on the system.
.SH SYNOPSIS
.B helpers
[-fln]
.SH DESCRIPTION
Helpers are users who volunteer to answer help requests by setting a help
flag. For more information, see the manual pages for
.IR mesg (1)
and
.IR write (1).
.PP
The
.I helpers
command
lists or counts the people who currently have helper flags set on the system.
It lists them by default, or if the
.B -l
flag is given.
It prints a count to standard output if the
.B -n
flag is given.
.PP
If the
.B -f
flag is given, only the helpers who are currently free are listed or counted.
.SH AUTHOR
Jan Wolter
.SH FILES
/etc/wrttmp
.SH "SEE ALSO"
mesg(1), write(1)
orville-write-2.55/say 0100755 0000765 0000765 00000001762 06673762525 013140 0 ustar jan jan #!/bin/sh
# "SAY" SCRIPT - A cheap simulution of the Well/River "say" command using
# Jan Wolter's "gate" and "write" programs.
#
# SYNOPSIS:
# say [user|-|.] [tty]
#
# DESCRIPTION:
# Say will prompt you to enter some text, and then send it in one burst
# to the named user. It is essentially similar to "tel" except that
# "tel" is limited to a single line of text.
#
# As with tel, the recipient must have message and telegram permissions
# enabled. If he has the "mesg -r" flag set, he will be able to redisplay
# the message with the "huh" command.
#
# Say will not work if system administrators have set the -f flag to be
# the default on "write."
#
# The two lines below should be set to the paths of the "gate" and "write"
# commands. "Red" could be used instead of "gate."
#
gate=/wolter/src/mnet/gate/gate
write=/wolter/src/mnet/write/write
rm=/bin/rm
#
file=/tmp/say$$
$gate --prompt="" --outdent=0 $file
if ($write $* < $file)
then
echo DONE
fi
rm -f $file
orville-write-2.55/Makefile.in 0100644 0000765 0000765 00000006765 10126427216 014452 0 ustar jan jan SHELL= /bin/sh
srcdir= @srcdir@
VPATH= @srcdir@
CC= @CC@
INSTALL= @INSTALL@
LN= @LN_S@
prefix= @prefix@
exec_prefix= @exec_prefix@
bindir= @bindir@
mandir= @mandir@
datadir= @datadir@
sysconfdir= @sysconfdir@
localstatedir= @localstatedir@
groupid= @group_id@
CPPFLAGS= @CPPFLAGS@
CFLAGS= @CFLAGS@
LDFLAGS= @LDFLAGS@
LIB= @LIBS@
all: write mesg amin huh helpers
WSRC= wrt_main.c wrt_type.c wrt_him.c wrt_me.c wrt_opt.c wrt_sig.c \
wrt_tty.c wrt_hist.c lib_common.c getutent.c
WOBJ= wrt_main.o wrt_type.o wrt_him.o wrt_me.o wrt_opt.o wrt_sig.o \
wrt_tty.o wrt_hist.o lib_common.o getutent.o
write: $(WOBJ)
$(CC) $(CFLAGS) -o write $(WOBJ) $(LIB)
wrt_main.o: wrt_main.c wrttmp.h write.h config.h orville.h
wrt_type.o: wrt_type.c wrttmp.h write.h config.h orville.h
wrt_him.o: wrt_him.c lib_common.h getutent.h wrttmp.h write.h config.h orville.h
wrt_me.o: wrt_me.c lib_common.h getutent.h wrttmp.h write.h config.h orville.h
wrt_opt.o: wrt_opt.c wrttmp.h write.h config.h orville.h
wrt_sig.o: wrt_sig.c wrttmp.h write.h config.h orville.h
wrt_tty.o: wrt_tty.c wrttmp.h write.h config.h orville.h
wrt_hist.o: wrt_hist.c wrttmp.h write.h config.h orville.h
lib_common.o:lib_common.c getutent.h lib_common.h wrttmp.h config.h orville.h
getutent.o: getutent.c getutent.h wrttmp.h config.h orville.h
mesg.o: mesg.c wrttmp.h lib_common.h config.h orville.h
amin.o: amin.c wrttmp.h lib_common.h config.h orville.h
huh.o: huh.c wrttmp.h lib_common.h config.h orville.h
helpers.o: helpers.c wrttmp.h getutent.h config.h orville.h
wt.o: wt.c wrttmp.h config.h orville.h
mesg: mesg.o lib_common.o getutent.o
$(CC) $(LDFLAGS) -o mesg mesg.o lib_common.o getutent.o
amin: amin.o lib_common.o getutent.o
$(CC) $(LDFLAGS) -o amin amin.o lib_common.o getutent.o
huh: huh.o lib_common.o getutent.o
$(CC) $(LDFLAGS) -o huh huh.o lib_common.o getutent.o
helpers: helpers.o getutent.o
$(CC) $(LDFLAGS) -o helpers helpers.o getutent.o lib_common.o
wt: wt.o
$(CC) $(LDFLAGS) -o wt wt.c lib_common.o getutent.o
install: write mesg amin huh helpers
./install-sh -d $(bindir)
$(INSTALL) -o root -g $(groupid) -m 6711 write $(bindir)
-(cd $(bindir); $(LN) write jot; $(LN) write tel; $(LN) write telegram)
$(INSTALL) -o root -m 4711 mesg $(bindir)
$(INSTALL) -o root -m 4711 amin $(bindir)
$(INSTALL) -o root -m 4711 huh $(bindir)
$(INSTALL) -m 4711 helpers $(bindir)
./install-sh -d $(sysconfdir)
$(INSTALL) -m 644 orville.conf $(sysconfdir)
-rm -f $(sysconfdir)/wrttmp
touch $(sysconfdir)/wrttmp
chown root $(sysconfdir)/wrttmp
chmod 600 $(sysconfdir)/wrttmp
-rm -f $(sysconfdir)/wrthist
touch $(sysconfdir)/wrthist
chmod 600 $(sysconfdir)/wrthist
./install-sh -d $(mandir)/man1
$(INSTALL) -m 644 write.1 $(mandir)/man1
$(INSTALL) -m 644 mesg.1 $(mandir)/man1
$(INSTALL) -m 644 amin.1 $(mandir)/man1
$(INSTALL) -m 644 huh.1 $(mandir)/man1
$(INSTALL) -m 644 helpers.1 $(mandir)/man1
write.tar: README INSTALLATION CHANGES $(WSRC) wrttmp.h write.h orville.h \
lib_common.h getutent.h mesg.c amin.c huh.c amin.1 write.1 mesg.1 \
huh.1 wrttab wt.c say Makefile.in configure.in configure install-sh \
config.h.in orville.conf
tar cvf write.tar README INSTALLATION CHANGES $(WSRC) write.h \
wrttmp.h orville.h lib_common.h getutent.h mesg.c amin.c huh.c amin.1 \
write.1 mesg.1 huh.1 wrttab wt.c helpers.c helpers.1 say \
Makefile.in configure.in configure install-sh config.h.in orville.conf
clean:
-rm -f wt core *.o
distclean:
-rm -f write mesg amin huh helpers wt core *.o config.h config.cache \
config.cache config.status Makefile write.tar
orville-write-2.55/configure.in 0100644 0000765 0000765 00000004025 07665676457 014734 0 ustar jan jan dnl Process this file with autoconf to produce a configure script.
AC_INIT(orville.h)
AC_CONFIG_HEADER(config.h)
AC_SUBST(group_id)
dnl Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_LN_S
dnl Checks for libraries.
AC_CHECK_LIB(crypt, crypt)
dnl Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_HEADER_TIME
AC_CHECK_HEADERS(fcntl.h paths.h sys/time.h unistd.h crypt.h)
AC_CHECK_HEADERS(termios.h termio.h sgtty.h, [break])
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_STRUCT_TM
AC_STRUCT_TIMEZONE
dnl Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_TYPE_SIGNAL
AC_CHECK_FUNCS(random getutent strchr)
AC_CHECK_FUNCS(getuserpw)
if test "$ac_cv_func_getuserpw" != "yes"; then
AC_SEARCH_LIBS(getspnam, shadow,
[ AC_DEFINE(HAVE_GETSPNAM)
AC_SEARCH_LIBS(kg_pwhash,shadow,
[ AC_DEFINE(HAVE_KG_PWHASH)],
[ AC_SEARCH_LIBS(pw_encrpyt,shadow, [AC_DEFINE(HAVE_PW_ENCRYPT)])])
])
fi
dnl Checks for flags
AC_ARG_WITH(slow_passwd,
[ --with-slow-passwd looking up people in /etc/passwd is slow],
[ if test "$enableval" != "no"; then
AC_DEFINE(SLOWPASSWD)
fi])
AC_ARG_WITH(talk,
[ --with-talk you have a talkd hacked for orville compatibility],
[ if test "$enableval" != "no"; then
AC_DEFINE(WITH_TALK)
fi])
dnl Unconditionally, for now. Later try to sense this.
AC_DEFINE(TTY_GROUP)
AC_CACHE_CHECK([for tty device group], ow_cv_tty_group_id, [dnl
changequote(, )dnl
tty=`tty`
ow_cv_tty_group_id=`ls -lg $tty | sed 's/^.*-[^ ]* *[^ ]* *[^ ]* *\([^ ]*\).*$/\1/'`
changequote([, ])dnl
])
group_id=$ow_cv_tty_group_id
dnl Path name of orville.conf file.
test "x$prefix" = xNONE && prefix=$ac_default_prefix
oc=`eval echo "${sysconfdir}/orville.conf" | sed "s/\/\//\//g"`
echo "Configuration file will be in $oc"
AC_DEFINE_UNQUOTED(ORVILLE_CONF,"$oc")
wt=`eval echo "${sysconfdir}/wrttmp" | sed "s/\/\//\//g"`
AC_DEFINE_UNQUOTED(D_WRTTMP,"$wt")
wh=`eval echo "${sysconfdir}/wrthist" | sed "s/\/\//\//g"`
AC_DEFINE_UNQUOTED(D_WRTHIST,"$wh")
AC_OUTPUT(Makefile)
orville-write-2.55/configure 0100755 0000765 0000765 00000203675 07665676463 014343 0 ustar jan jan #! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated automatically using autoconf version 2.13
# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
# Defaults:
ac_help=
ac_default_prefix=/usr/local
# Any additions from configure.in:
ac_help="$ac_help
--with-slow-passwd looking up people in /etc/passwd is slow"
ac_help="$ac_help
--with-talk you have a talkd hacked for orville compatibility"
# Initialize some variables set by options.
# The variables have the same names as the options, with
# dashes changed to underlines.
build=NONE
cache_file=./config.cache
exec_prefix=NONE
host=NONE
no_create=
nonopt=NONE
no_recursion=
prefix=NONE
program_prefix=NONE
program_suffix=NONE
program_transform_name=s,x,x,
silent=
site=
srcdir=
target=NONE
verbose=
x_includes=NONE
x_libraries=NONE
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datadir='${prefix}/share'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
libdir='${exec_prefix}/lib'
includedir='${prefix}/include'
oldincludedir='/usr/include'
infodir='${prefix}/info'
mandir='${prefix}/man'
# Initialize some other variables.
subdirs=
MFLAGS= MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}
# Maximum number of lines to put in a shell here document.
ac_max_here_lines=12
ac_prev=
for ac_option
do
# If the previous option needs an argument, assign it.
if test -n "$ac_prev"; then
eval "$ac_prev=\$ac_option"
ac_prev=
continue
fi
case "$ac_option" in
-*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) ac_optarg= ;;
esac
# Accept the important Cygnus configure options, so we can diagnose typos.
case "$ac_option" in
-bindir | --bindir | --bindi | --bind | --bin | --bi)
ac_prev=bindir ;;
-bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
bindir="$ac_optarg" ;;
-build | --build | --buil | --bui | --bu)
ac_prev=build ;;
-build=* | --build=* | --buil=* | --bui=* | --bu=*)
build="$ac_optarg" ;;
-cache-file | --cache-file | --cache-fil | --cache-fi \
| --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
ac_prev=cache_file ;;
-cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
| --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
cache_file="$ac_optarg" ;;
-datadir | --datadir | --datadi | --datad | --data | --dat | --da)
ac_prev=datadir ;;
-datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
| --da=*)
datadir="$ac_optarg" ;;
-disable-* | --disable-*)
ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
# Reject names that are not valid shell variable names.
if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
{ echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
fi
ac_feature=`echo $ac_feature| sed 's/-/_/g'`
eval "enable_${ac_feature}=no" ;;
-enable-* | --enable-*)
ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
# Reject names that are not valid shell variable names.
if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
{ echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
fi
ac_feature=`echo $ac_feature| sed 's/-/_/g'`
case "$ac_option" in
*=*) ;;
*) ac_optarg=yes ;;
esac
eval "enable_${ac_feature}='$ac_optarg'" ;;
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
| --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
| --exec | --exe | --ex)
ac_prev=exec_prefix ;;
-exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
| --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
| --exec=* | --exe=* | --ex=*)
exec_prefix="$ac_optarg" ;;
-gas | --gas | --ga | --g)
# Obsolete; use --with-gas.
with_gas=yes ;;
-help | --help | --hel | --he)
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat << EOF
Usage: configure [options] [host]
Options: [defaults in brackets after descriptions]
Configuration:
--cache-file=FILE cache test results in FILE
--help print this message
--no-create do not create output files
--quiet, --silent do not print \`checking...' messages
--version print the version of autoconf that created configure
Directory and file names:
--prefix=PREFIX install architecture-independent files in PREFIX
[$ac_default_prefix]
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
[same as prefix]
--bindir=DIR user executables in DIR [EPREFIX/bin]
--sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
--libexecdir=DIR program executables in DIR [EPREFIX/libexec]
--datadir=DIR read-only architecture-independent data in DIR
[PREFIX/share]
--sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data in DIR
[PREFIX/com]
--localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
--libdir=DIR object code libraries in DIR [EPREFIX/lib]
--includedir=DIR C header files in DIR [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
--infodir=DIR info documentation in DIR [PREFIX/info]
--mandir=DIR man documentation in DIR [PREFIX/man]
--srcdir=DIR find the sources in DIR [configure dir or ..]
--program-prefix=PREFIX prepend PREFIX to installed program names
--program-suffix=SUFFIX append SUFFIX to installed program names
--program-transform-name=PROGRAM
run sed PROGRAM on installed program names
EOF
cat << EOF
Host type:
--build=BUILD configure for building on BUILD [BUILD=HOST]
--host=HOST configure for HOST [guessed]
--target=TARGET configure for TARGET [TARGET=HOST]
Features and packages:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--x-includes=DIR X include files are in DIR
--x-libraries=DIR X library files are in DIR
EOF
if test -n "$ac_help"; then
echo "--enable and --with options recognized:$ac_help"
fi
exit 0 ;;
-host | --host | --hos | --ho)
ac_prev=host ;;
-host=* | --host=* | --hos=* | --ho=*)
host="$ac_optarg" ;;
-includedir | --includedir | --includedi | --included | --include \
| --includ | --inclu | --incl | --inc)
ac_prev=includedir ;;
-includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
| --includ=* | --inclu=* | --incl=* | --inc=*)
includedir="$ac_optarg" ;;
-infodir | --infodir | --infodi | --infod | --info | --inf)
ac_prev=infodir ;;
-infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
infodir="$ac_optarg" ;;
-libdir | --libdir | --libdi | --libd)
ac_prev=libdir ;;
-libdir=* | --libdir=* | --libdi=* | --libd=*)
libdir="$ac_optarg" ;;
-libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
| --libexe | --libex | --libe)
ac_prev=libexecdir ;;
-libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
| --libexe=* | --libex=* | --libe=*)
libexecdir="$ac_optarg" ;;
-localstatedir | --localstatedir | --localstatedi | --localstated \
| --localstate | --localstat | --localsta | --localst \
| --locals | --local | --loca | --loc | --lo)
ac_prev=localstatedir ;;
-localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
| --localstate=* | --localstat=* | --localsta=* | --localst=* \
| --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
localstatedir="$ac_optarg" ;;
-mandir | --mandir | --mandi | --mand | --man | --ma | --m)
ac_prev=mandir ;;
-mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
mandir="$ac_optarg" ;;
-nfp | --nfp | --nf)
# Obsolete; use --without-fp.
with_fp=no ;;
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
| --no-cr | --no-c)
no_create=yes ;;
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
| --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
no_recursion=yes ;;
-oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
| --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
| --oldin | --oldi | --old | --ol | --o)
ac_prev=oldincludedir ;;
-oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
| --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
| --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
oldincludedir="$ac_optarg" ;;
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
ac_prev=prefix ;;
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
prefix="$ac_optarg" ;;
-program-prefix | --program-prefix | --program-prefi | --program-pref \
| --program-pre | --program-pr | --program-p)
ac_prev=program_prefix ;;
-program-prefix=* | --program-prefix=* | --program-prefi=* \
| --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
program_prefix="$ac_optarg" ;;
-program-suffix | --program-suffix | --program-suffi | --program-suff \
| --program-suf | --program-su | --program-s)
ac_prev=program_suffix ;;
-program-suffix=* | --program-suffix=* | --program-suffi=* \
| --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
program_suffix="$ac_optarg" ;;
-program-transform-name | --program-transform-name \
| --program-transform-nam | --program-transform-na \
| --program-transform-n | --program-transform- \
| --program-transform | --program-transfor \
| --program-transfo | --program-transf \
| --program-trans | --program-tran \
| --progr-tra | --program-tr | --program-t)
ac_prev=program_transform_name ;;
-program-transform-name=* | --program-transform-name=* \
| --program-transform-nam=* | --program-transform-na=* \
| --program-transform-n=* | --program-transform-=* \
| --program-transform=* | --program-transfor=* \
| --program-transfo=* | --program-transf=* \
| --program-trans=* | --program-tran=* \
| --progr-tra=* | --program-tr=* | --program-t=*)
program_transform_name="$ac_optarg" ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
| --sbi=* | --sb=*)
sbindir="$ac_optarg" ;;
-sharedstatedir | --sharedstatedir | --sharedstatedi \
| --sharedstated | --sharedstate | --sharedstat | --sharedsta \
| --sharedst | --shareds | --shared | --share | --shar \
| --sha | --sh)
ac_prev=sharedstatedir ;;
-sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
| --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
| --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
| --sha=* | --sh=*)
sharedstatedir="$ac_optarg" ;;
-site | --site | --sit)
ac_prev=site ;;
-site=* | --site=* | --sit=*)
site="$ac_optarg" ;;
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
srcdir="$ac_optarg" ;;
-sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
| --syscon | --sysco | --sysc | --sys | --sy)
ac_prev=sysconfdir ;;
-sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
| --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
sysconfdir="$ac_optarg" ;;
-target | --target | --targe | --targ | --tar | --ta | --t)
ac_prev=target ;;
-target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
target="$ac_optarg" ;;
-v | -verbose | --verbose | --verbos | --verbo | --verb)
verbose=yes ;;
-version | --version | --versio | --versi | --vers)
echo "configure generated by autoconf version 2.13"
exit 0 ;;
-with-* | --with-*)
ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
# Reject names that are not valid shell variable names.
if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
{ echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
fi
ac_package=`echo $ac_package| sed 's/-/_/g'`
case "$ac_option" in
*=*) ;;
*) ac_optarg=yes ;;
esac
eval "with_${ac_package}='$ac_optarg'" ;;
-without-* | --without-*)
ac_package=`echo $ac_option|sed -e 's/-*without-//'`
# Reject names that are not valid shell variable names.
if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
{ echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
fi
ac_package=`echo $ac_package| sed 's/-/_/g'`
eval "with_${ac_package}=no" ;;
--x)
# Obsolete; use --with-x.
with_x=yes ;;
-x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
| --x-incl | --x-inc | --x-in | --x-i)
ac_prev=x_includes ;;
-x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
| --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
x_includes="$ac_optarg" ;;
-x-libraries | --x-libraries | --x-librarie | --x-librari \
| --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
ac_prev=x_libraries ;;
-x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
x_libraries="$ac_optarg" ;;
-*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
;;
*)
if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
echo "configure: warning: $ac_option: invalid host type" 1>&2
fi
if test "x$nonopt" != xNONE; then
{ echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
fi
nonopt="$ac_option"
;;
esac
done
if test -n "$ac_prev"; then
{ echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
fi
trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
# File descriptor usage:
# 0 standard input
# 1 file creation
# 2 errors and warnings
# 3 some systems may open it to /dev/tty
# 4 used on the Kubota Titan
# 6 checking for... messages and results
# 5 compiler messages saved in config.log
if test "$silent" = yes; then
exec 6>/dev/null
else
exec 6>&1
fi
exec 5>./config.log
echo "\
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
" 1>&5
# Strip out --no-create and --no-recursion so they do not pile up.
# Also quote any args containing shell metacharacters.
ac_configure_args=
for ac_arg
do
case "$ac_arg" in
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
| --no-cr | --no-c) ;;
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
| --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
*" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
ac_configure_args="$ac_configure_args '$ac_arg'" ;;
*) ac_configure_args="$ac_configure_args $ac_arg" ;;
esac
done
# NLS nuisances.
# Only set these to C if already set. These must not be set unconditionally
# because not all systems understand e.g. LANG=C (notably SCO).
# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
# Non-C LC_CTYPE values break the ctype check.
if test "${LANG+set}" = set; then LANG=C; export LANG; fi
if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -rf conftest* confdefs.h
# AIX cpp loses on an empty file, so make sure it contains at least a newline.
echo > confdefs.h
# A filename unique to this package, relative to the directory that
# configure is in, which we can look for to find out if srcdir is correct.
ac_unique_file=orville.h
# Find the source files, if location was not specified.
if test -z "$srcdir"; then
ac_srcdir_defaulted=yes
# Try the directory containing this script, then its parent.
ac_prog=$0
ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
srcdir=$ac_confdir
if test ! -r $srcdir/$ac_unique_file; then
srcdir=..
fi
else
ac_srcdir_defaulted=no
fi
if test ! -r $srcdir/$ac_unique_file; then
if test "$ac_srcdir_defaulted" = yes; then
{ echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
else
{ echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
fi
fi
srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
# Prefer explicitly selected file to automatically selected ones.
if test -z "$CONFIG_SITE"; then
if test "x$prefix" != xNONE; then
CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
else
CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
fi
fi
for ac_site_file in $CONFIG_SITE; do
if test -r "$ac_site_file"; then
echo "loading site script $ac_site_file"
. "$ac_site_file"
fi
done
if test -r "$cache_file"; then
echo "loading cache $cache_file"
. $cache_file
else
echo "creating cache $cache_file"
> $cache_file
fi
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross
ac_exeext=
ac_objext=o
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
# Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
ac_n= ac_c='
' ac_t=' '
else
ac_n=-n ac_c= ac_t=
fi
else
ac_n= ac_c='\c' ac_t=
fi
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:535: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_CC="gcc"
break
fi
done
IFS="$ac_save_ifs"
fi
fi
CC="$ac_cv_prog_CC"
if test -n "$CC"; then
echo "$ac_t""$CC" 1>&6
else
echo "$ac_t""no" 1>&6
fi
if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:565: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_prog_rejected=no
ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
ac_prog_rejected=yes
continue
fi
ac_cv_prog_CC="cc"
break
fi
done
IFS="$ac_save_ifs"
if test $ac_prog_rejected = yes; then
# We found a bogon in the path, so make sure we never use it.
set dummy $ac_cv_prog_CC
shift
if test $# -gt 0; then
# We chose a different compiler from the bogus one.
# However, it has the same basename, so the bogon will be chosen
# first if we set CC to just the basename; use the full file name.
shift
set dummy "$ac_dir/$ac_word" "$@"
shift
ac_cv_prog_CC="$@"
fi
fi
fi
fi
CC="$ac_cv_prog_CC"
if test -n "$CC"; then
echo "$ac_t""$CC" 1>&6
else
echo "$ac_t""no" 1>&6
fi
if test -z "$CC"; then
case "`uname -s`" in
*win32* | *WIN32*)
# Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:616: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_CC="cl"
break
fi
done
IFS="$ac_save_ifs"
fi
fi
CC="$ac_cv_prog_CC"
if test -n "$CC"; then
echo "$ac_t""$CC" 1>&6
else
echo "$ac_t""no" 1>&6
fi
;;
esac
fi
test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
echo "configure:648: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext << EOF
#line 659 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
if { (eval echo configure:664: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
ac_cv_prog_cc_cross=no
else
ac_cv_prog_cc_cross=yes
fi
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_prog_cc_works=no
fi
rm -fr conftest*
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross
echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
if test $ac_cv_prog_cc_works = no; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
echo "configure:690: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
echo "configure:695: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
fi
fi
echo "$ac_t""$ac_cv_prog_gcc" 1>&6
if test $ac_cv_prog_gcc = yes; then
GCC=yes
else
GCC=
fi
ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
echo "configure:723: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
echo 'void f(){}' > conftest.c
if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
ac_cv_prog_cc_g=yes
else
ac_cv_prog_cc_g=no
fi
rm -f conftest*
fi
echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
if test "$ac_test_CFLAGS" = set; then
CFLAGS="$ac_save_CFLAGS"
elif test $ac_cv_prog_cc_g = yes; then
if test "$GCC" = yes; then
CFLAGS="-g -O2"
else
CFLAGS="-g"
fi
else
if test "$GCC" = yes; then
CFLAGS="-O2"
else
CFLAGS=
fi
fi
ac_aux_dir=
for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
if test -f $ac_dir/install-sh; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/install-sh -c"
break
elif test -f $ac_dir/install.sh; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/install.sh -c"
break
fi
done
if test -z "$ac_aux_dir"; then
{ echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
fi
ac_config_guess=$ac_aux_dir/config.guess
ac_config_sub=$ac_aux_dir/config.sub
ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
# incompatible versions:
# SysV /etc/install, /usr/sbin/install
# SunOS /usr/etc/install
# IRIX /sbin/install
# AIX /bin/install
# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
echo "configure:785: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
for ac_dir in $PATH; do
# Account for people who put trailing slashes in PATH elements.
case "$ac_dir/" in
/|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
*)
# OSF1 and SCO ODT 3.0 have their own names for install.
# Don't use installbsd from OSF since it installs stuff as root
# by default.
for ac_prog in ginstall scoinst install; do
if test -f $ac_dir/$ac_prog; then
if test $ac_prog = install &&
grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
:
else
ac_cv_path_install="$ac_dir/$ac_prog -c"
break 2
fi
fi
done
;;
esac
done
IFS="$ac_save_IFS"
fi
if test "${ac_cv_path_install+set}" = set; then
INSTALL="$ac_cv_path_install"
else
# As a last resort, use the slow shell script. We don't cache a
# path for INSTALL within a source directory, because that will
# break other packages using the cache if that directory is
# removed, or if the path is relative.
INSTALL="$ac_install_sh"
fi
fi
echo "$ac_t""$INSTALL" 1>&6
# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
# It thinks the first close brace ends the variable substitution.
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
echo "configure:838: checking whether ln -s works" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
rm -f conftestdata
if ln -s X conftestdata 2>/dev/null
then
rm -f conftestdata
ac_cv_prog_LN_S="ln -s"
else
ac_cv_prog_LN_S=ln
fi
fi
LN_S="$ac_cv_prog_LN_S"
if test "$ac_cv_prog_LN_S" = "ln -s"; then
echo "$ac_t""yes" 1>&6
else
echo "$ac_t""no" 1>&6
fi
echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
echo "configure:860: checking for crypt in -lcrypt" >&5
ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lcrypt $LIBS"
cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"
fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_lib=HAVE_LIB`echo crypt | sed -e 's/[^a-zA-Z0-9_]/_/g' \
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
cat >> confdefs.h <&6
fi
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
echo "configure:908: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
fi
if test -z "$CPP"; then
if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# This must be in double quotes, not single quotes, because CPP may get
# substituted into the Makefile and "${CC-cc}" will confuse make.
CPP="${CC-cc} -E"
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:929: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
else
echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:946: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
else
echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:963: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
else
echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
CPP=/lib/cpp
fi
rm -f conftest*
fi
rm -f conftest*
fi
rm -f conftest*
ac_cv_prog_CPP="$CPP"
fi
CPP="$ac_cv_prog_CPP"
else
ac_cv_prog_CPP="$CPP"
fi
echo "$ac_t""$CPP" 1>&6
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
echo "configure:988: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <
#include
#include
#include
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1001: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
ac_cv_header_stdc=yes
else
echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_header_stdc=no
fi
rm -f conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
egrep "memchr" >/dev/null 2>&1; then
:
else
rm -rf conftest*
ac_cv_header_stdc=no
fi
rm -f conftest*
fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
egrep "free" >/dev/null 2>&1; then
:
else
rm -rf conftest*
ac_cv_header_stdc=no
fi
rm -f conftest*
fi
if test $ac_cv_header_stdc = yes; then
# /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
int main () { int i; for (i = 0; i < 256; i++)
if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
if { (eval echo configure:1068: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -fr conftest*
ac_cv_header_stdc=no
fi
rm -fr conftest*
fi
fi
fi
echo "$ac_t""$ac_cv_header_stdc" 1>&6
if test $ac_cv_header_stdc = yes; then
cat >> confdefs.h <<\EOF
#define STDC_HEADERS 1
EOF
fi
echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
echo "configure:1092: checking for sys/wait.h that is POSIX.1 compatible" >&5
if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <
#include
#ifndef WEXITSTATUS
#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
#endif
#ifndef WIFEXITED
#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
#endif
int main() {
int s;
wait (&s);
s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
; return 0; }
EOF
if { (eval echo configure:1113: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_sys_wait_h=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_header_sys_wait_h=no
fi
rm -f conftest*
fi
echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
if test $ac_cv_header_sys_wait_h = yes; then
cat >> confdefs.h <<\EOF
#define HAVE_SYS_WAIT_H 1
EOF
fi
echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
echo "configure:1134: checking whether time.h and sys/time.h may both be included" >&5
if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <
#include
#include
int main() {
struct tm *tp;
; return 0; }
EOF
if { (eval echo configure:1148: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_time=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_header_time=no
fi
rm -f conftest*
fi
echo "$ac_t""$ac_cv_header_time" 1>&6
if test $ac_cv_header_time = yes; then
cat >> confdefs.h <<\EOF
#define TIME_WITH_SYS_TIME 1
EOF
fi
for ac_hdr in fcntl.h paths.h sys/time.h unistd.h crypt.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:1172: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1182: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
else
echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_header_$ac_safe=no"
fi
rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
cat >> confdefs.h <&6
fi
done
for ac_hdr in termios.h termio.h sgtty.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:1213: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1223: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
else
echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_header_$ac_safe=no"
fi
rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
cat >> confdefs.h <&6
fi
done
echo $ac_n "checking for working const""... $ac_c" 1>&6
echo "configure:1251: checking for working const" >&5
if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <j = 5;
}
{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
const int foo = 10;
}
; return 0; }
EOF
if { (eval echo configure:1305: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_const=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_c_const=no
fi
rm -f conftest*
fi
echo "$ac_t""$ac_cv_c_const" 1>&6
if test $ac_cv_c_const = no; then
cat >> confdefs.h <<\EOF
#define const
EOF
fi
echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
echo "configure:1326: checking whether struct tm is in sys/time.h or time.h" >&5
if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <
#include
int main() {
struct tm *tp; tp->tm_sec;
; return 0; }
EOF
if { (eval echo configure:1339: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_tm=time.h
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_struct_tm=sys/time.h
fi
rm -f conftest*
fi
echo "$ac_t""$ac_cv_struct_tm" 1>&6
if test $ac_cv_struct_tm = sys/time.h; then
cat >> confdefs.h <<\EOF
#define TM_IN_SYS_TIME 1
EOF
fi
echo $ac_n "checking for tm_zone in struct tm""... $ac_c" 1>&6
echo "configure:1360: checking for tm_zone in struct tm" >&5
if eval "test \"`echo '$''{'ac_cv_struct_tm_zone'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <
#include <$ac_cv_struct_tm>
int main() {
struct tm tm; tm.tm_zone;
; return 0; }
EOF
if { (eval echo configure:1373: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_tm_zone=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_struct_tm_zone=no
fi
rm -f conftest*
fi
echo "$ac_t""$ac_cv_struct_tm_zone" 1>&6
if test "$ac_cv_struct_tm_zone" = yes; then
cat >> confdefs.h <<\EOF
#define HAVE_TM_ZONE 1
EOF
else
echo $ac_n "checking for tzname""... $ac_c" 1>&6
echo "configure:1393: checking for tzname" >&5
if eval "test \"`echo '$''{'ac_cv_var_tzname'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <
#ifndef tzname /* For SGI. */
extern char *tzname[]; /* RS6000 and others reject char **tzname. */
#endif
int main() {
atoi(*tzname);
; return 0; }
EOF
if { (eval echo configure:1408: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_var_tzname=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_var_tzname=no
fi
rm -f conftest*
fi
echo "$ac_t""$ac_cv_var_tzname" 1>&6
if test $ac_cv_var_tzname = yes; then
cat >> confdefs.h <<\EOF
#define HAVE_TZNAME 1
EOF
fi
fi
if test $ac_cv_prog_gcc = yes; then
echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
echo "configure:1432: checking whether ${CC-cc} needs -traditional" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_pattern="Autoconf.*'x'"
cat > conftest.$ac_ext <
Autoconf TIOCGETP
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
egrep "$ac_pattern" >/dev/null 2>&1; then
rm -rf conftest*
ac_cv_prog_gcc_traditional=yes
else
rm -rf conftest*
ac_cv_prog_gcc_traditional=no
fi
rm -f conftest*
if test $ac_cv_prog_gcc_traditional = no; then
cat > conftest.$ac_ext <
Autoconf TCGETA
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
egrep "$ac_pattern" >/dev/null 2>&1; then
rm -rf conftest*
ac_cv_prog_gcc_traditional=yes
fi
rm -f conftest*
fi
fi
echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
if test $ac_cv_prog_gcc_traditional = yes; then
CC="$CC -traditional"
fi
fi
echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
echo "configure:1478: checking return type of signal handlers" >&5
if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <
#include
#ifdef signal
#undef signal
#endif
#ifdef __cplusplus
extern "C" void (*signal (int, void (*)(int)))(int);
#else
void (*signal ()) ();
#endif
int main() {
int i;
; return 0; }
EOF
if { (eval echo configure:1500: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_type_signal=void
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_type_signal=int
fi
rm -f conftest*
fi
echo "$ac_t""$ac_cv_type_signal" 1>&6
cat >> confdefs.h <&6
echo "configure:1521: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char $ac_func();
int main() {
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
choke me
#else
$ac_func();
#endif
; return 0; }
EOF
if { (eval echo configure:1549: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_func_$ac_func=no"
fi
rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
cat >> confdefs.h <&6
fi
done
for ac_func in getuserpw
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:1576: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char $ac_func();
int main() {
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
choke me
#else
$ac_func();
#endif
; return 0; }
EOF
if { (eval echo configure:1604: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_func_$ac_func=no"
fi
rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
cat >> confdefs.h <&6
fi
done
if test "$ac_cv_func_getuserpw" != "yes"; then
echo $ac_n "checking for library containing getspnam""... $ac_c" 1>&6
echo "configure:1632: checking for library containing getspnam" >&5
if eval "test \"`echo '$''{'ac_cv_search_getspnam'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_func_search_save_LIBS="$LIBS"
ac_cv_search_getspnam="no"
cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_search_getspnam="none required"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest*
test "$ac_cv_search_getspnam" = "no" && for i in shadow; do
LIBS="-l$i $ac_func_search_save_LIBS"
cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_search_getspnam="-l$i"
break
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest*
done
LIBS="$ac_func_search_save_LIBS"
fi
echo "$ac_t""$ac_cv_search_getspnam" 1>&6
if test "$ac_cv_search_getspnam" != "no"; then
test "$ac_cv_search_getspnam" = "none required" || LIBS="$ac_cv_search_getspnam $LIBS"
cat >> confdefs.h <<\EOF
#define HAVE_GETSPNAM 1
EOF
echo $ac_n "checking for library containing kg_pwhash""... $ac_c" 1>&6
echo "configure:1694: checking for library containing kg_pwhash" >&5
if eval "test \"`echo '$''{'ac_cv_search_kg_pwhash'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_func_search_save_LIBS="$LIBS"
ac_cv_search_kg_pwhash="no"
cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_search_kg_pwhash="none required"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest*
test "$ac_cv_search_kg_pwhash" = "no" && for i in shadow; do
LIBS="-l$i $ac_func_search_save_LIBS"
cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_search_kg_pwhash="-l$i"
break
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest*
done
LIBS="$ac_func_search_save_LIBS"
fi
echo "$ac_t""$ac_cv_search_kg_pwhash" 1>&6
if test "$ac_cv_search_kg_pwhash" != "no"; then
test "$ac_cv_search_kg_pwhash" = "none required" || LIBS="$ac_cv_search_kg_pwhash $LIBS"
cat >> confdefs.h <<\EOF
#define HAVE_KG_PWHASH 1
EOF
else :
echo $ac_n "checking for library containing pw_encrpyt""... $ac_c" 1>&6
echo "configure:1757: checking for library containing pw_encrpyt" >&5
if eval "test \"`echo '$''{'ac_cv_search_pw_encrpyt'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_func_search_save_LIBS="$LIBS"
ac_cv_search_pw_encrpyt="no"
cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_search_pw_encrpyt="none required"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest*
test "$ac_cv_search_pw_encrpyt" = "no" && for i in shadow; do
LIBS="-l$i $ac_func_search_save_LIBS"
cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_search_pw_encrpyt="-l$i"
break
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest*
done
LIBS="$ac_func_search_save_LIBS"
fi
echo "$ac_t""$ac_cv_search_pw_encrpyt" 1>&6
if test "$ac_cv_search_pw_encrpyt" != "no"; then
test "$ac_cv_search_pw_encrpyt" = "none required" || LIBS="$ac_cv_search_pw_encrpyt $LIBS"
cat >> confdefs.h <<\EOF
#define HAVE_PW_ENCRYPT 1
EOF
else :
fi
fi
else :
fi
fi
# Check whether --with-slow_passwd or --without-slow_passwd was given.
if test "${with_slow_passwd+set}" = set; then
withval="$with_slow_passwd"
if test "$enableval" != "no"; then
cat >> confdefs.h <<\EOF
#define SLOWPASSWD 1
EOF
fi
fi
# Check whether --with-talk or --without-talk was given.
if test "${with_talk+set}" = set; then
withval="$with_talk"
if test "$enableval" != "no"; then
cat >> confdefs.h <<\EOF
#define WITH_TALK 1
EOF
fi
fi
cat >> confdefs.h <<\EOF
#define TTY_GROUP 1
EOF
echo $ac_n "checking for tty device group""... $ac_c" 1>&6
echo "configure:1858: checking for tty device group" >&5
if eval "test \"`echo '$''{'ow_cv_tty_group_id'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
tty=`tty`
ow_cv_tty_group_id=`ls -lg $tty | sed 's/^.*-[^ ]* *[^ ]* *[^ ]* *\([^ ]*\).*$/\1/'`
fi
echo "$ac_t""$ow_cv_tty_group_id" 1>&6
group_id=$ow_cv_tty_group_id
test "x$prefix" = xNONE && prefix=$ac_default_prefix
oc=`eval echo "${sysconfdir}/orville.conf" | sed "s/\/\//\//g"`
echo "Configuration file will be in $oc"
cat >> confdefs.h <> confdefs.h <> confdefs.h < confcache <<\EOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs. It is not useful on other systems.
# If it contains results you don't want to keep, you may remove or edit it.
#
# By default, configure uses ./config.cache as the cache file,
# creating it if it does not exist already. You can give configure
# the --cache-file=FILE option to use a different cache file; that is
# what configure does when it calls configure scripts in
# subdirectories, so they share the cache.
# Giving --cache-file=/dev/null disables caching, for debugging configure.
# config.status only pays attention to the cache file if you give it the
# --recheck option to rerun configure.
#
EOF
# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, don't put newlines in cache variables' values.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(set) 2>&1 |
case `(ac_space=' '; set | grep ac_space) 2>&1` in
*ac_space=\ *)
# `set' does not quote correctly, so add quotes (double-quote substitution
# turns \\\\ into \\, and sed turns \\ into \).
sed -n \
-e "s/'/'\\\\''/g" \
-e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
;;
*)
# `set' quotes correctly as required by POSIX, so do not add quotes.
sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
;;
esac >> confcache
if cmp -s $cache_file confcache; then
:
else
if test -w $cache_file; then
echo "updating cache $cache_file"
cat confcache > $cache_file
else
echo "not updating unwritable cache $cache_file"
fi
fi
rm -f confcache
trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
# Any assignment to VPATH causes Sun make to only execute
# the first set of double-colon rules, so remove it if not needed.
# If there is a colon in the path, we need to keep it.
if test "x$srcdir" = x.; then
ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
fi
trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
DEFS=-DHAVE_CONFIG_H
# Without the "./", some shells look in PATH for config.status.
: ${CONFIG_STATUS=./config.status}
echo creating $CONFIG_STATUS
rm -f $CONFIG_STATUS
cat > $CONFIG_STATUS </dev/null | sed 1q`:
#
# $0 $ac_configure_args
#
# Compiler output produced by configure, useful for debugging
# configure, is in ./config.log if it exists.
ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
for ac_option
do
case "\$ac_option" in
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-version | --version | --versio | --versi | --vers | --ver | --ve | --v)
echo "$CONFIG_STATUS generated by autoconf version 2.13"
exit 0 ;;
-help | --help | --hel | --he | --h)
echo "\$ac_cs_usage"; exit 0 ;;
*) echo "\$ac_cs_usage"; exit 1 ;;
esac
done
ac_given_srcdir=$srcdir
ac_given_INSTALL="$INSTALL"
trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
EOF
cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF
$ac_vpsub
$extrasub
s%@SHELL@%$SHELL%g
s%@CFLAGS@%$CFLAGS%g
s%@CPPFLAGS@%$CPPFLAGS%g
s%@CXXFLAGS@%$CXXFLAGS%g
s%@FFLAGS@%$FFLAGS%g
s%@DEFS@%$DEFS%g
s%@LDFLAGS@%$LDFLAGS%g
s%@LIBS@%$LIBS%g
s%@exec_prefix@%$exec_prefix%g
s%@prefix@%$prefix%g
s%@program_transform_name@%$program_transform_name%g
s%@bindir@%$bindir%g
s%@sbindir@%$sbindir%g
s%@libexecdir@%$libexecdir%g
s%@datadir@%$datadir%g
s%@sysconfdir@%$sysconfdir%g
s%@sharedstatedir@%$sharedstatedir%g
s%@localstatedir@%$localstatedir%g
s%@libdir@%$libdir%g
s%@includedir@%$includedir%g
s%@oldincludedir@%$oldincludedir%g
s%@infodir@%$infodir%g
s%@mandir@%$mandir%g
s%@group_id@%$group_id%g
s%@CC@%$CC%g
s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
s%@INSTALL_DATA@%$INSTALL_DATA%g
s%@LN_S@%$LN_S%g
s%@CPP@%$CPP%g
CEOF
EOF
cat >> $CONFIG_STATUS <<\EOF
# Split the substitutions into bite-sized pieces for seds with
# small command number limits, like on Digital OSF/1 and HP-UX.
ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
ac_file=1 # Number of current file.
ac_beg=1 # First line for current file.
ac_end=$ac_max_sed_cmds # Line after last line for current file.
ac_more_lines=:
ac_sed_cmds=""
while $ac_more_lines; do
if test $ac_beg -gt 1; then
sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
else
sed "${ac_end}q" conftest.subs > conftest.s$ac_file
fi
if test ! -s conftest.s$ac_file; then
ac_more_lines=false
rm -f conftest.s$ac_file
else
if test -z "$ac_sed_cmds"; then
ac_sed_cmds="sed -f conftest.s$ac_file"
else
ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
fi
ac_file=`expr $ac_file + 1`
ac_beg=$ac_end
ac_end=`expr $ac_end + $ac_max_sed_cmds`
fi
done
if test -z "$ac_sed_cmds"; then
ac_sed_cmds=cat
fi
EOF
cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case "$ac_file" in
*:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
*) ac_file_in="${ac_file}.in" ;;
esac
# Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
# Remove last slash and all that follows it. Not all systems have dirname.
ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
# The file is in a subdirectory.
test ! -d "$ac_dir" && mkdir "$ac_dir"
ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
# A "../" for each directory in $ac_dir_suffix.
ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
else
ac_dir_suffix= ac_dots=
fi
case "$ac_given_srcdir" in
.) srcdir=.
if test -z "$ac_dots"; then top_srcdir=.
else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
/*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
*) # Relative path.
srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
top_srcdir="$ac_dots$ac_given_srcdir" ;;
esac
case "$ac_given_INSTALL" in
[/$]*) INSTALL="$ac_given_INSTALL" ;;
*) INSTALL="$ac_dots$ac_given_INSTALL" ;;
esac
echo creating "$ac_file"
rm -f "$ac_file"
configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
case "$ac_file" in
*Makefile*) ac_comsub="1i\\
# $configure_input" ;;
*) ac_comsub= ;;
esac
ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
sed -e "$ac_comsub
s%@configure_input@%$configure_input%g
s%@srcdir@%$srcdir%g
s%@top_srcdir@%$top_srcdir%g
s%@INSTALL@%$INSTALL%g
" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
fi; done
rm -f conftest.s*
# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
# NAME is the cpp macro being defined and VALUE is the value it is being given.
#
# ac_d sets the value in "#define NAME VALUE" lines.
ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
ac_dC='\3'
ac_dD='%g'
# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
ac_uB='\([ ]\)%\1#\2define\3'
ac_uC=' '
ac_uD='\4%g'
# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
ac_eB='$%\1#\2define\3'
ac_eC=' '
ac_eD='%g'
if test "${CONFIG_HEADERS+set}" != set; then
EOF
cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF
fi
for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case "$ac_file" in
*:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
*) ac_file_in="${ac_file}.in" ;;
esac
echo creating $ac_file
rm -f conftest.frag conftest.in conftest.out
ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
cat $ac_file_inputs > conftest.in
EOF
# Transform confdefs.h into a sed script conftest.vals that substitutes
# the proper values into config.h.in to produce config.h. And first:
# Protect against being on the right side of a sed subst in config.status.
# Protect against being in an unquoted here document in config.status.
rm -f conftest.vals
cat > conftest.hdr <<\EOF
s/[\\&%]/\\&/g
s%[\\$`]%\\&%g
s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
s%ac_d%ac_u%gp
s%ac_u%ac_e%gp
EOF
sed -n -f conftest.hdr confdefs.h > conftest.vals
rm -f conftest.hdr
# This sed command replaces #undef with comments. This is necessary, for
# example, in the case of _POSIX_SOURCE, which is predefined and required
# on some systems where configure will not decide to define it.
cat >> conftest.vals <<\EOF
s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
EOF
# Break up conftest.vals because some shells have a limit on
# the size of here documents, and old seds have small limits too.
rm -f conftest.tail
while :
do
ac_lines=`grep -c . conftest.vals`
# grep -c gives empty output for an empty file on some AIX systems.
if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
# Write a limited-size here document to conftest.frag.
echo ' cat > conftest.frag <> $CONFIG_STATUS
sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
echo 'CEOF
sed -f conftest.frag conftest.in > conftest.out
rm -f conftest.in
mv conftest.out conftest.in
' >> $CONFIG_STATUS
sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
rm -f conftest.vals
mv conftest.tail conftest.vals
done
rm -f conftest.vals
cat >> $CONFIG_STATUS <<\EOF
rm -f conftest.frag conftest.h
echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
cat conftest.in >> conftest.h
rm -f conftest.in
if cmp -s $ac_file conftest.h 2>/dev/null; then
echo "$ac_file is unchanged"
rm -f conftest.h
else
# Remove last slash and all that follows it. Not all systems have dirname.
ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
# The file is in a subdirectory.
test ! -d "$ac_dir" && mkdir "$ac_dir"
fi
rm -f $ac_file
mv conftest.h $ac_file
fi
fi; done
EOF
cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF
exit 0
EOF
chmod +x $CONFIG_STATUS
rm -fr confdefs* $ac_clean_files
test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
orville-write-2.55/install-sh 0100755 0000765 0000765 00000012736 07042760056 014411 0 ustar jan jan #!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0
orville-write-2.55/config.h.in 0100644 0000765 0000765 00000004620 07665676751 014444 0 ustar jan jan #ifndef CONFIG_H
#define CONFIG_H
/* Path name of configuration file. */
#undef ORVILLE_CONF
/* Default location of wrttmp file. */
#undef D_WRTTMP
/* Default location of wrthist file. */
#undef D_WRTHIST
/* Define if we want to be talk compatible. */
#undef WITH_TALK
/* Define if password file lookups are extremely slow on your system */
#undef SLOWPASSWD
/* Define if tty devices are normally permitted only to group */
#undef TTY_GROUP
/* Define if tty devices are normally permitted to others */
#undef TTY_OTHERS
/* Define to empty if the keyword does not work. */
#undef const
/* Define if you have that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
/* Define as the return type of signal handlers (int or void). */
#undef RETSIGTYPE
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define if you do password lookups with the getuserpw() function. */
#undef HAVE_GETUSERPW
/* Define if passwords in your shadow file are encrypted by pw_encrypt() */
#undef HAVE_PW_ENCRYPT
/* Define if passwords in your shadow file are encrypted by kg_pwhash() */
#undef HAVE_KG_PWHASH
/* Define if your declares struct tm. */
#undef TM_IN_SYS_TIME
/* Define if you do password lookups with the getspnam() function. */
#undef HAVE_GETSPNAM
/* Define if you have the random() function. */
#undef HAVE_RANDOM
/* Define if you have the strchr() function. */
#undef HAVE_STRCHR
/* Define if you have the getutent() function. */
#undef HAVE_GETUTENT
/* Define if you have the header file. */
#undef HAVE_CRYPT_H
/* Define if you have the header file. */
#undef HAVE_FCNTL_H
/* Define if you have the header file. */
#undef HAVE_PATHS_H
/* Define if you have the header file. */
#undef HAVE_SGTTY_H
/* Define if you have the header file. */
#undef HAVE_SYS_TIME_H
/* Define if you may include both time.h and sys/time.h */
#undef TIME_WITH_SYS_TIME
/* Define if you have the header file. */
#undef HAVE_TERMIO_H
/* Define if you have the header file. */
#undef HAVE_TERMIOS_H
/* Define if you have the header file. */
#undef HAVE_UNISTD_H
/* Define if you have the crypt library (-lcrypt). */
#undef HAVE_LIBCRYPT
/* Define if 'struct tm' has a tm_zone member */
#undef HAVE_TM_ZONE
/* Define if we have external array 'tzname' */
#undef HAVE_TZNAME
#endif /* CONFIG_H */
orville-write-2.55/orville.conf 0100644 0000765 0000765 00000006416 07044405013 014715 0 ustar jan jan # ===== FILES =====
# Wrttmp File - Location of the file where all current user's write settings
# are kept. If not defined, this defaults to being named 'wrttmp' and being
# in the same directory as orville.conf.
# wrttmp /etc/wrttmp
# Wrthist File - Location of file where records of recent telgrams are saved.
# are kept. If not defined, this defaults to being named 'wrthist' and being
# in the same directory as orville.conf.
# wrthist /etc/wrthist
# Novice Help - If it is defined and exists, then contents of this file are
# printed when help starts up if they have the NOVICE environment variable set.
novicehelp /usr/local/share/write.help
# ===== LOGGING =====
# Log file - Keeps a record of who wrote whom, whether the connection worked,
# and what went wrong if it didn't. If loglevel is 0, or is not defined, or
# the file does not exist, then no log is kept.
log /var/log/write.log
# Log Level - How much shall we log? Value should be:
# 0 - nothing.
# 1 - help requests only (good for monitoring how your help is doing)
# 2 - all writes attempts.
loglevel 1
# ===== OPTIONS =====
# Disconnect flag - Set to 'y' if you want people to be able to disconnect
# all write sessions currently directed at them with 'mesg d' or 'mesg N'.
# Default is 'y'.
# disconnect y
# Exceptions flag - Set to 'y' if you want people to be able to turn messages
# on or off with the exception of a list of users named in the .nowrite or
# .yeswrite files. Default is 'y'.
# exceptions y
# Helpers flag - Set to 'y' if you want 'write help' to connect people to a
# helper. Default is 'n'
# helpers n
# Time to Answer Telegrams - After you send a telegram to a person, there
# is a period of time during which that person may reply, even if your
# permissions are off. The answertel command sets the length of that period
# in seconds. Default is 240 seconds (4 minutes).
# answertel 300
# Hostname on Message Banners - Many versions of write send banners like
# "Message from user@hostname". This is nice if the recipient is in a telnet
# connection to another Unix system, so the writes could be coming from either
# of two systems. It defaults off because I have an irrational dislike for it.
# fromhost n
# Allow Piped Input - If 'pipes' is turned off, then standard input to write
# must be a tty, not a pipe, and the '|' and '&' escapes are disabled. It
# is useful if you have cretinous users who like sending large globs of data
# to other users.
# pipes y
# ===== HELPERS =====
# Helper name - If instead of writing 'help' you'd like people to write to
# some other name to get help, set that name here. Default is 'help'.
# helpername help
# Helpers file - If this is defined, and the file exists, then only people
# named in this file can do 'mesg -h' and become helpers. If not, anyone can
# designate themselves to be a helper. Just list one login id per line in
# the file.
helperlist /usr/local/etc/helplist
# No Helper file - Contains a message to print when a person does 'write help'
# but no helpers are found. Usually a description of alternate places to get
# help. If not defined, no message is printed.
nohelp /usr/local/share/write.nohelp
# ===== LINKS =====
# Default options for various links to the Orville write program
options jot -c
options tel -t
options telegram -t
orville-write-2.55/config.log 0100644 0000765 0000765 00000013727 10126432501 014342 0 ustar jan jan This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
configure:535: checking for gcc
configure:648: checking whether the C compiler (gcc ) works
configure:664: gcc -o conftest conftest.c 1>&5
configure:690: checking whether the C compiler (gcc ) is a cross-compiler
configure:695: checking whether we are using GNU C
configure:704: gcc -E conftest.c
configure:723: checking whether gcc accepts -g
configure:785: checking for a BSD compatible install
configure:838: checking whether ln -s works
configure:860: checking for crypt in -lcrypt
configure:879: gcc -o conftest -g -O2 conftest.c -lcrypt 1>&5
configure:908: checking how to run the C preprocessor
configure:929: gcc -E conftest.c >/dev/null 2>conftest.out
configure:988: checking for ANSI C header files
configure:1001: gcc -E conftest.c >/dev/null 2>conftest.out
configure:1068: gcc -o conftest -g -O2 conftest.c -lcrypt 1>&5
configure:1092: checking for sys/wait.h that is POSIX.1 compatible
configure:1113: gcc -c -g -O2 conftest.c 1>&5
configure:1134: checking whether time.h and sys/time.h may both be included
configure:1148: gcc -c -g -O2 conftest.c 1>&5
configure:1172: checking for fcntl.h
configure:1182: gcc -E conftest.c >/dev/null 2>conftest.out
configure:1172: checking for paths.h
configure:1182: gcc -E conftest.c >/dev/null 2>conftest.out
configure:1172: checking for sys/time.h
configure:1182: gcc -E conftest.c >/dev/null 2>conftest.out
configure:1172: checking for unistd.h
configure:1182: gcc -E conftest.c >/dev/null 2>conftest.out
configure:1172: checking for crypt.h
configure:1182: gcc -E conftest.c >/dev/null 2>conftest.out
configure:1213: checking for termios.h
configure:1223: gcc -E conftest.c >/dev/null 2>conftest.out
configure:1251: checking for working const
configure:1305: gcc -c -g -O2 conftest.c 1>&5
configure:1326: checking whether struct tm is in sys/time.h or time.h
configure:1339: gcc -c -g -O2 conftest.c 1>&5
configure:1360: checking for tm_zone in struct tm
configure:1373: gcc -c -g -O2 conftest.c 1>&5
configure:1432: checking whether gcc needs -traditional
configure:1478: checking return type of signal handlers
configure:1500: gcc -c -g -O2 conftest.c 1>&5
configure:1521: checking for random
configure:1549: gcc -o conftest -g -O2 conftest.c -lcrypt 1>&5
configure:1521: checking for getutent
configure:1549: gcc -o conftest -g -O2 conftest.c -lcrypt 1>&5
configure:1521: checking for strchr
configure:1549: gcc -o conftest -g -O2 conftest.c -lcrypt 1>&5
configure:1533: warning: conflicting types for built-in function `strchr'
configure:1576: checking for getuserpw
configure:1604: gcc -o conftest -g -O2 conftest.c -lcrypt 1>&5
/home/jan/tmp/ccSBSOVN.o(.text+0x9): In function `main':
/home/jan/src/write/orville-write-2.55/configure:1598: undefined reference to `getuserpw'
collect2: ld returned 1 exit status
configure: failed program was:
#line 1581 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char getuserpw(); below. */
#include
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char getuserpw();
int main() {
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_getuserpw) || defined (__stub___getuserpw)
choke me
#else
getuserpw();
#endif
; return 0; }
configure:1632: checking for library containing getspnam
configure:1650: gcc -o conftest -g -O2 conftest.c -lcrypt 1>&5
configure:1694: checking for library containing kg_pwhash
configure:1712: gcc -o conftest -g -O2 conftest.c -lcrypt 1>&5
/home/jan/tmp/ccwck4vL.o(.text+0x9): In function `main':
/home/jan/src/write/orville-write-2.55/configure:1708: undefined reference to `kg_pwhash'
collect2: ld returned 1 exit status
configure: failed program was:
#line 1701 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char kg_pwhash();
int main() {
kg_pwhash()
; return 0; }
configure:1734: gcc -o conftest -g -O2 conftest.c -lshadow -lcrypt 1>&5
/usr/bin/ld: cannot find -lshadow
collect2: ld returned 1 exit status
configure: failed program was:
#line 1723 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char kg_pwhash();
int main() {
kg_pwhash()
; return 0; }
configure:1757: checking for library containing pw_encrpyt
configure:1775: gcc -o conftest -g -O2 conftest.c -lcrypt 1>&5
/home/jan/tmp/ccItJtKB.o(.text+0x9): In function `main':
/home/jan/src/write/orville-write-2.55/configure:1771: undefined reference to `pw_encrpyt'
collect2: ld returned 1 exit status
configure: failed program was:
#line 1764 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char pw_encrpyt();
int main() {
pw_encrpyt()
; return 0; }
configure:1797: gcc -o conftest -g -O2 conftest.c -lshadow -lcrypt 1>&5
/usr/bin/ld: cannot find -lshadow
collect2: ld returned 1 exit status
configure: failed program was:
#line 1786 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char pw_encrpyt();
int main() {
pw_encrpyt()
; return 0; }
configure:1858: checking for tty device group