v13i066: BSD File delivery programs
Rich Salz
rsalz at bbn.com
Wed Feb 24 21:00:33 AEST 1988
Submitted-by: Scooter Morris <scooter at genie.gene.com>
Posting-number: Volume 13, Issue 66
Archive-name: ups
[ Great name and concept, even if of unknown utility. --r$ ]
This program allows users on 4.3bsd systems to pass around files in
a manner very similar to mail. It uses the network and the /usr/lib/aliases
file to handle sending files to users on other machines.
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# README
# Makefile
# ups.c
# upsd.c
# ups.l
export PATH; PATH=/bin:$PATH
if test -f 'README'
then
echo shar: will not over-write existing file "'README'"
else
cat << \SHAR_EOF > 'README'
README for ups - the package delivery system
ups is a system (actually just two programs) for delivering files between
users. It works just like mail, except that accepting delivery implies
the movement of files. Basically, a user just types to the shell the
following:
ups user file1 file2 ...
this will cause the files file1, file2, ... to be copied into a spool area
and a mail message to be sent to 'user' informing them that there are files
awaiting them in ups. To receive the files a user simply types 'ups' to
the shell and gets a list of files which are awaiting delivery and is
asked if they wish to accept delivery in the current directory.
What's required
ups was written for a 4.3bsd network of vaxes. It will probably work on
a 2.9 or 4.2 system without a lot of work. Other machines will certainly
require work.
Installation
1) Add ups to the table of known ports in /etc/services as follows:
ups 600/tcp
2) Add ups to the inetd configuration file /etc/inetd.conf:
ups stream tcp nowait root /usr/local/lib/upsd upsd
3) Make ups and upsd by just saying "make all"
4) And finally install ups and upsd. We installed upsd in /usr/local/lib
(as shown above) and this is where make install will put it.
We also added a line to our standard .login file of the form: ups -q. This will
inform users at login time if files are awaiting them.
SHAR_EOF
fi # end of overwriting check
if test -f 'Makefile'
then
echo shar: will not over-write existing file "'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
# $Header: Makefile,v 1.1 85/08/21 22:39:19 scooter Exp $
UPSDIR = "/usr/spool/ups"
SENDMAIL = "/usr/lib/sendmail"
BIN = "/usr/local/bin"
LIB = "/usr/local/lib"
# CFLAGS = -O -g -D'UPSDIR=$(UPSDIR)' -D'SENDMAIL=$(SENDMAIL)' -DDEBUG -DALIASES
CFLAGS = -O -D'UPSDIR=$(UPSDIR)' -D'SENDMAIL=$(SENDMAIL)' -DALIASES
VPATH = ./RCS
.SUFFIXES: .c,v
all: ups upsd
install: ups upsd
cp ups $(BIN)/ups
cp upsd $(LIB)/upsd
.c,v.o:
co -q $*.c
cc $(CFLAGS) -c $*.c
mv $*.o OBJS
rm -f $*.c
ups: ups.o
cc $(CFLAGS) -o ups ups.o
upsd: upsd.o
cc $(CFLAGS) -o upsd upsd.o
SHAR_EOF
fi # end of overwriting check
if test -f 'ups.c'
then
echo shar: will not over-write existing file "'ups.c'"
else
cat << \SHAR_EOF > 'ups.c'
#ifndef lint
static char RCSid[] = "$Header: ups.c,v 1.8 86/12/11 15:58:18 scooter Exp $";
#endif
/*
* ups - user interface to the package delivery system
*
* usage: ups user at host file1 file2 ...
*
* $Author: scooter $
* $Revision: 1.8 $
* $Date: 86/12/11 15:58:18 $
*
* $Log: ups.c,v $
* Revision 1.8 86/12/11 15:58:18 scooter
* Added alias expansion code which allows ups to follow /usr/lib/aliases.
*
* Revision 1.7 86/09/19 18:53:15 scooter
* Added -i option for mail specification
*
* Revision 1.6 86/09/18 15:19:45 scooter
* More fixes to the '.' problam
*
* Revision 1.5 86/09/17 09:43:38 scooter
* Added code to do automatic renaming of "." files for delivery to
* avoid the "cannot delete" problem
*
* Revision 1.4 85/08/21 22:27:45 scooter
* Release revision: added more complete RCS headers.
*
*/
#include <stdio.h>
#include <pwd.h>
#include <ndbm.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <netdb.h>
#include <ctype.h>
#define LS "/bin/ls"
struct passwd *getpwuid();
FILE *fopen();
int rem;
int qflg = 0;
int iflg = 0;
int on = 1;
char buffer[BUFSIZ*5];
char mbuffer[BUFSIZ*4];
struct user_list {
char *u_user;
char *u_host;
struct user_list *u_next;
};
main(argc, argv)
char **argv;
int argc;
{
char myhost[BUFSIZ];
int file;
int ret;
char *user,*host,*tmp,*rindex(),*index();
struct passwd *mypwent;
struct user_list *u_list,*u_top, *alias_expand();
gethostname(myhost,BUFSIZ);
if( (mypwent = getpwuid(getuid())) == NULL )
{
fprintf(stderr,"ups: who are you?\n");
exit(1);
}
while (*argv[1] == '-')
{
char c;
switch (c = *(++argv[1]))
{
case 'q':
qflg++;
break;
case 'i':
iflg++;
break;
default:
fprintf(stderr,"ups: unknown option %c\n",c);
}
argv++;
argc--;
}
if (argc == 1 || qflg)
upsread(mypwent);
if (argc == 2) {
fprintf(stderr,"usage: ups user at host file1 file2 ...\n");
exit(0);
}
/*
* Get the name of the destination user and host
*/
user = argv[1];
host = rindex(user,'@');
#ifndef ALIASES
if (host == NULL)
host = myhost;
else
*host++ = '\0';
#else
if (host != NULL)
*host++ = '\0';
u_top = alias_expand(user,host,myhost);
#endif ALIASES
if (iflg)
upsgetmsg(mbuffer);
else
mbuffer[0] = '\0';
while (u_top != NULL)
{
#ifdef DEBUG
printf("Connecting to %s for user %s\n",u_top->u_host,u_top->u_user);
#endif DEBUG
rem = upsconnect(u_top->u_host); /* Connect to the server */
/*
* Send the to name, from name, and our name
*/
tmp = index(mypwent->pw_gecos,',');
if (tmp)
*tmp = '\0';
sprintf(buffer, "%s\n%s\n%s\n%s", u_top->u_user,
mypwent->pw_name, mypwent->pw_gecos,mbuffer);
#ifdef DEBUG
printf("Sending: %s\n",buffer);
fflush(stdout);
#endif DEBUG
write(rem, buffer, strlen(buffer)+1);
ret = read(rem, buffer, BUFSIZ);
if (buffer[0])
problem(1);
for (file = 2 ; file < argc ; file++)
{
#ifdef DEBUG
printf("Sending file: %s",argv[file]);
#endif DEBUG
sendfile(argv[file]);
}
sprintf(buffer, "-Done-");
write(rem, buffer, strlen(buffer)+1);
read(rem, buffer, BUFSIZ); /* get result */
if (buffer[0]) /* problem? */
problem(1); /* yes, go handle it */
close(rem);
u_top = u_top->u_next;
}
}
upsconnect(host)
char *host;
{
struct hostent *hp;
struct servent *sp;
struct sockaddr_in sin;
int s;
hp = gethostbyname(host);
if (hp == NULL) {
static struct hostent def;
static struct in_addr defaddr;
static char namebuf[128];
int inet_addr();
defaddr.s_addr = inet_addr(host);
if (defaddr.s_addr == -1) {
printf("unknown host: %s\n", host);
exit(1);
}
strcpy(namebuf, host);
def.h_name = namebuf;
def.h_addr = (char *)&defaddr;
def.h_length = sizeof (struct in_addr);
def.h_addrtype = AF_INET;
def.h_aliases = 0;
hp = &def;
}
sp = getservbyname("ups", "tcp");
if (sp == 0) {
fprintf(stderr,"tcp/ups: unknown service\n");
exit(1);
}
sin.sin_family = hp->h_addrtype;
bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
sin.sin_port = sp->s_port;
s = socket(hp->h_addrtype, SOCK_STREAM, 0);
if (s < 0) {
fflush(stderr);
perror("ups (socket)");
exit(1);
}
setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,&on,sizeof(on));
#ifdef DEBUG
setsockopt(s,SOL_SOCKET,SO_DEBUG,&on,sizeof(on));
#endif DEBUG
if (connect(s, (char *)&sin, sizeof (sin)) < 0) {
fflush(stderr);
perror("ups (connect)");
close(s);
exit(1);
}
return(s);
}
sendfile(file)
char *file;
{
struct stat fstatus;
int loc,n;
char *tmp,*fname;
if ( (loc = open(file,O_RDONLY)) <= 0 ) {
perror("ups (open)");
return(1);
}
if (fstat(loc, &fstatus)) {
perror("ups (fstat)");
return(1);
}
if ((fstatus.st_mode&S_IFMT) != S_IFREG) {
switch (fstatus.st_mode&S_IFMT)
{
case S_IFDIR:
tmp = "directory";
break;
case S_IFCHR:
tmp = "character device";
break;
case S_IFBLK:
tmp = "block device";
break;
case S_IFLNK:
tmp = "symbolic link";
break;
case S_IFSOCK:
tmp = "socket";
break;
}
fprintf(stderr,
"ups: %s is a %s, only regular files may be sent\n",
file,tmp);
fflush(stderr);
return(1);
}
/*
* Send the file name
*/
/*
* First strip off the directory path
*/
sprintf(buffer,"%s",file);
tmp = rindex(buffer,'/');
if (tmp)
*tmp++ = '\0';
else
tmp = buffer;
fname = tmp;
if (*tmp == '.')
{
while ( (*tmp == '.') && (*tmp != '\0') )tmp++;
fprintf(stdout,
"WARNING: file %s has been renamed to %s for delivery\n",
fname,tmp);
}
write(rem, tmp, strlen(tmp)+1);
read(rem, buffer, BUFSIZ);
if (buffer[0]) /* problem */
{
problem(0);
return(1);
}
/*
* Send the file size in bytes
*/
sprintf(buffer, "%D",fstatus.st_size);
write(rem, buffer, strlen(buffer)+1);
read(rem, buffer, BUFSIZ);
if (buffer[0]) /* problem */
{
problem(0);
return(1);
}
/*
* Send the file
*/
while (n = read(loc, buffer, BUFSIZ))
write(rem, buffer, n);
close(loc);
read(rem, buffer, BUFSIZ); /* get result */
if (buffer[0]) /* problem */
{
problem(0);
return(1);
}
sprintf(buffer, "%u", fstatus.st_mode);
write(rem, buffer, strlen(buffer)+1);
read(rem, buffer, BUFSIZ); /* get result */
if (buffer[0]) /* problem */
{
problem(0);
return(1);
}
return(0);
}
upsread(mypwent)
struct passwd *mypwent;
{
union wait status;
int pid;
char c,line[BUFSIZ],*tmp;
sprintf(buffer,"%s/%s",UPSDIR,mypwent->pw_name);
if (qflg)
{
if (!access(buffer,F_OK)) {
fprintf(stderr,
"You have ups files awaiting you (type ups to accept delivery)\n");
}
exit(0);
}
if (access(buffer,F_OK)) {
fprintf(stderr,"Nothing waiting in ups\n");
exit(0);
}
fprintf(stdout,"\nYou have the following files awaiting delivery:\n\n");
if (pid = vfork())
{
wait(&status);
} else {
execl(LS,"ls","-C",buffer,(char *)0);
perror("ups (exec)");
return(0);
}
fprintf(stdout,"\n");
fprintf(stdout,
"Do you wish to accept delivery in your\n");
fprintf(stdout,
"current directory (%s)? ",
getwd(line));
getinp:
if (fgets(line,BUFSIZ,stdin) == NULL) {
fprintf(stdout,"\n");
exit(0);
}
tmp = &line[0];
while (isspace(*tmp)) tmp++;
switch (*tmp) {
case 'y':
case 'Y':
sprintf(line,"mv -i %s/* . ; rmdir %s",buffer,buffer);
system(line);
exit(0);
case 'n':
case 'N':
exit(0);
default:
fprintf(stdout,"Please answer 'yes' or 'no': ");
goto getinp;
}
}
/*
* problem() is called when the install demon process return a non-zero reply.
* This usually means something recognizable went wrong and we should expect
* a reason to follow. Read in the reason, output it on the terminal and die.
*/
problem(die)
int die;
{
char buf[BUFSIZ]; /* place to read into */
if (read(rem, buf, BUFSIZ) > 0) /* if we have something */
fprintf(stderr, "ups: %s", buf);
if (die) {
close(rem); /* close network channel */
exit(1);
}
}
int
upsgetmsg(mailbuffer)
char *mailbuffer;
{
int done = 0;
fprintf(stdout,
"Enter your message followed by '.<RETURN>' or a <CTRL>D:\n");
while (!done)
{
fprintf(stdout,"> ");
if (gets(mailbuffer) == NULL)
{
fprintf(stdout,"\n");
done++;
} else if ( (*mailbuffer == '.') && (*(mailbuffer+1) == '\0'))
{
done++;
*mailbuffer = '\0';
} else {
while(*mailbuffer != '\0')
mailbuffer++;
*mailbuffer++ = '\n';
*mailbuffer = '\0';
}
}
fprintf(stdout,"[EOT]\n");
}
struct user_list *
alias_expand(user,host,myhost)
char *user,*host,*myhost;
{
char *malloc();
DBM *dp;
datum key,content;
struct user_list *list,*top,*alloc_list();
char *cp,*tp,*hp;
list = top = (struct user_list *)NULL;
if (host != NULL)
return(alloc_list(user,host));
dp = dbm_open("/usr/lib/aliases", O_RDONLY, 0644);
if (dp == NULL)
return(alloc_list(user,host));
key.dptr = user;
key.dsize = strlen(user) + 1;
content = dbm_fetch(dp,key);
if (content.dptr == NULL)
return(alloc_list(user,myhost));
cp = content.dptr;
while (cp != NULL)
{
tp = cp;
cp = index(cp,',');
if (cp != NULL)
*cp++ = '\0';
if (index(tp,'!')) {
fprintf(stderr,
"ups: WARNING: cannot alias %s to %s (no ups over uucp)\n",
user,hp);
continue;
} else if(index(tp,'|')) {
fprintf(stderr,
"ups: WARNING: cannot alias %s to %s (no shells allowed)\n",
user,hp);
continue;
}
hp = tp;
hp = index(tp,'@');
if (hp == NULL)
hp = myhost;
else
*hp++ = '\0';
if (top == NULL)
top = list = alloc_list(tp,hp);
else
{
list->u_next = alloc_list(tp,hp);
list = list->u_next;
}
}
return(top);
}
struct user_list *
alloc_list(user,host)
char *user,*host;
{
char *malloc();
struct user_list *list;
list = (struct user_list *)malloc(sizeof(struct user_list));
list->u_user = malloc(strlen(user) + 1);
list->u_host = malloc(strlen(host) + 1);
strcpy(list->u_user,user);
strcpy(list->u_host,host);
list->u_next = (struct user_list *)NULL;
return(list);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'upsd.c'
then
echo shar: will not over-write existing file "'upsd.c'"
else
cat << \SHAR_EOF > 'upsd.c'
#ifndef lint
static char RCSid[] = "$Header: upsd.c,v 1.4 86/11/19 15:21:52 scooter Exp $";
#endif
/*
* upsd - package delivery server
*
* upsd is the program that is called by inetd when a ups
* request is issued. It will read and write to standard input
* and standard output. Here is a description of the ups
* protocol:
*
* ups upsd type
*
* user_name ------> login name of package receiver String
* from_name ------> login name of package sender String
* full_name ------> full name of package sender String
* message ------> mail message to send String
* <----- 0 for OK Byte
* For each file:
* file_name ------> name of file to be delivered String
* file_size ------> size of file in bytes Long
* <----- 0 for OK Byte
* file ------> file size bytes
* <----- 0 for OK Byte
* file_mode ------> file mode Int
* <----- 0 for OK Byte
*
* When its all done:
* complete ------> We're done ('-Done-') String
* <----- 0 for OK Byte
*
* $Author: scooter $
* $Revision: 1.4 $
* $Date: 86/11/19 15:21:52 $
*
* $Log: upsd.c,v $
* Revision 1.4 86/11/19 15:21:52 scooter
* Changed error severity level from ERR to INFO
*
* Revision 1.3 86/09/19 18:53:37 scooter
* Added -i option for mail specification.
* Also added syslog stuff.
*
* Revision 1.2 85/08/21 22:28:11 scooter
* Release revision: added more complete RCS headers.
*
*
*/
#include <stdio.h>
#include <pwd.h>
#include <grp.h>
#include <sys/file.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <syslog.h>
long atol();
int atoi();
char buffer[BUFSIZ*5]; /* character input buffer */
char file_name[BUFSIZ]; /* file name */
char file_path[BUFSIZ]; /* full path to destination */
char user_name[BUFSIZ]; /* Receiver name */
char from_name[BUFSIZ]; /* Sender name */
char full_name[BUFSIZ]; /* Full name of sender */
char file_list[BUFSIZ]; /* List of all files */
long file_size; /* number of bytes in file */
int file_mode; /* mode of the file */
char mail_message[BUFSIZ*4]; /* mail message */
int mcount; /* number of characters in mail buffer */
int fid; /* File descriptor for destination */
int debugflag; /* Debug flag */
main(argc, argv)
int argc;
char **argv;
{
char *ptr,*tptr,*mptr;
int f, i, file;
struct sockaddr_in sin;
struct hostent *peer;
struct passwd *pwent;
while (*argv[1] == '-')
{
char c;
switch (c = *(++argv[1]))
{
case 'd':
debugflag++;
break;
default:
fprintf(stderr,"upsd: unknown option %c\n",c);
}
argv++;
argc--;
}
openlog("upsd",LOG_ODELAY,LOG_DAEMON);
if (debugflag)
syslog(LOG_DEBUG,"started");
i = sizeof (sin);
if (getpeername(0, &sin, &i) < 0)
syslog(LOG_ERR,"getpeername failed: %m");
if (debugflag)
syslog(LOG_DEBUG,"Calling gethostbyaddr");
peer = gethostbyaddr((char *)&sin.sin_addr,
sizeof(sin.sin_addr),sin.sin_family);
buffer[0] = '\0';
file_list[0] = '\0';
if (debugflag)
syslog(LOG_DEBUG,"Reading first buffer");
read(0, buffer, BUFSIZ*5); /* fetch receiver and sender names */
if (debugflag)
syslog(LOG_DEBUG,"receiver/sender/message: %s",buffer);
ptr = buffer;
while (*ptr != '\n')
ptr++;
*ptr++ = NULL;
strcpy(user_name, buffer); /* save receiver name */
tptr = ptr;
while (*tptr != '\n')
tptr++;
*tptr++ = NULL;
strcpy(from_name, ptr); /* save sender name */
mptr = tptr;
while ((*mptr != '\n') && (*mptr != '\0'))
mptr++;
*mptr++ = NULL;
strcpy (full_name, tptr); /* save sender's full name */
strcpy (mail_message, mptr); /* save the mail message */
/*
* Check for a valid user
*/
if ((pwent = getpwnam(user_name)))
ack();
else
{
error("Receiver name","No such person");
exit(1);
}
mcount = strlen (mail_message);
if (debugflag)
syslog(LOG_DEBUG,"mail message (%d chars):\n %s", mcount, mail_message);
for (file = 0 ;;)
{
if (read(0, buffer, BUFSIZ) <= 0) {
error("file name","premature EOF or file read error");
continue;
}
strcpy(file_name,buffer);
if (debugflag)
syslog(LOG_DEBUG,"File name:%s",file_name);
/*
* Are we done??
*/
if (!strncmp(file_name,"-Done-",6)) break;
if ( (fid = opendest(user_name,file_name,
pwent->pw_uid,pwent->pw_gid)) <= 0 )
{
continue;
}
ack();
if (read(0, buffer, BUFSIZ) <= 0) {
error("file size","premature EOF or file read error");
continue;
}
file_size = atol(buffer); /* get number of bytes */
ack();
copyfile(&file);
if (read(0, buffer, BUFSIZ) <= 0) {
error("file mode","premature EOF or file read error");
continue;
}
file_mode = atoi(buffer); /* get the file mode */
file_mode &= 0700; /* Strip the low order modes */
if (chmod(file_path,file_mode)) {
error("file mode","chmod failed");
continue;
}
ack();
chown(file_path,pwent->pw_uid,pwent->pw_gid);
}
ack();
if (file)
sendmail(from_name,full_name,peer->h_name,
user_name,file_list,file++,mail_message,mcount);
}
/*
copyfile
copyfile will copy file_size many bytes from stdin to a temporarily created
file. The filename will be passed back via buffer.
*/
copyfile(file)
int *file;
{
long cnt; /* file size counter */
int i;
cnt = file_size; /* count down input bytes */
while (cnt > 0) {
i = read(0, buffer, BUFSIZ);
write(fid, buffer, i);
cnt -= i;
}
close(fid);
ack();
sprintf(buffer,"%-15s",file_name);
if (*file%4)
strcat(file_list," ");
else
strcat(file_list,"\n\t");
(*file)++;
strcat(file_list,buffer);
}
/*
error(option, string)
char *option, *string;
This routine is called when some error condition has been encountered.
option contains an identifier message, while string contains the actual
error message. Before message is printed, a non-null character is output
first, then the string error message.
*/
error(option, string)
char *option, *string;
{
char buf[BUFSIZ];
buf[0] = 1;
write(1, buf, 1); /* nak */
sprintf(buf, "upsd: %s: %s\n", option, string);
write(1, buf, strlen(buf)+1);
syslog(LOG_INFO,"error - %s",buf);
}
/*
* ack()
* This routine is called to return an OK to the remote host.
*/
ack()
{
buffer[0] = 0;
write(1,buffer,1);
}
/*
* opendest(name,file)
* char *name,*file;
*
* Open the destination file "file" in UPSDIR/user, creating the
* file if necessary.
*/
int
opendest(name,file,uid,gid)
char *name,*file;
int uid,gid;
{
int ret;
sprintf(file_path,"%s/%s",UPSDIR,name); /* Form path to directory */
if (access(file_path,F_OK) == (-1))
{
mkdir(file_path,0700);
chown(file_path,uid,gid);
}
sprintf(file_path,"%s/%s/%s",UPSDIR,name,file);
if (!access(file_path,F_OK))
{
error("file creation","A file by that name has already been sent to that user.");
return(0);
} else {
ret = open(file_path,O_WRONLY|O_CREAT,0600);
if (ret <= 0)
{
sprintf(buffer,"unable to open destination file: %s",
file_path);
error("file open",buffer);
return(0);
}
return(ret);
}
}
/*
* sendmail(from,full,from_host,to,list,mess,count)
* char *from,*full,*to,*from_host,*list,*mess;
* int count;
*
* This routine sends mail to the destination user to inform
* them that ups files are awaiting them.
*/
sendmail(from,full,from_host,to,list,file,mess,count)
char *from,*full,*to,*from_host,*list,*mess;
int file,count;
{
FILE *send,*popen();
static char myhost[BUFSIZ];
gethostname(myhost,BUFSIZ);
sprintf(buffer,"%s -f%s@%s -F\"%s\" -t",SENDMAIL,from,from_host,full);
if(debugflag)
syslog(LOG_DEBUG,"sendmail\n%s",buffer);
send = popen(buffer,"w");
fprintf(send,"To: %s@%s\n",to,myhost);
if(debugflag)
syslog(LOG_DEBUG,"To: %s@%s",to,myhost);
fprintf(send,"Subject: UPS delivery\n");
if (file > 1)
strcpy(buffer,"files");
else
strcpy(buffer,"file");
fprintf(send,"I have sent you the following %s using ups:\n",buffer);
fprintf(send,"%s\n\n",list);
if (file > 1)
strcpy(buffer,"these files");
else
strcpy(buffer,"this file");
fprintf(send,"To retrieve %s, use the ups command.\n\n\n",buffer);
if (count)
fprintf(send,"%s\n",mess);
else
fprintf(send,"\n\n\n\n---ups\n");
pclose(send);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'ups.l'
then
echo shar: will not over-write existing file "'ups.l'"
else
cat << \SHAR_EOF > 'ups.l'
.TH UPS LOCAL
.UC 2
.SH NAME
ups \- send files to another user
.SH SYNOPSIS
.B ups [\-i]
user[@host]
file(s)
.br
.B ups
.br
.B ups \-q
.SH DESCRIPTION
The first form of the command
sends copies of files to another user.
The specified files are copied
into a special spool directory until the receiver
retrieves them.
The receiver is notified via \fImail\fR that the files are waiting.
.PP
The receiver of the files is specified by typing his/her
login id. If you don't know the login id of the receiver,
type \fIfinger\fR, space, followed by the name of the receiver.
For example, typing \fIfinger polly\fR would give information,
including login name, for all users named "polly", and
\fIfinger polly at genie\fR would give information, including login
name, for all users named "polly" on the machine "genie". If the
user you were interested in sending files to had the login name "pam"
you could send her files using the command:
.IP
\fIups pam at genie file1 ~ckw/file2\fR
.PP
This command will send the two files to \fIpam\fR.
.PP
The
.B \-i
flag is used when the user wishes to interactively specify their own
message to be appended to the mail sent to the receiver.
.PP
The second form of the command is used to receive the files
awaiting delivery in the spool directory. The user is shown
what files are available and asked if he/she wants to accept
delivery. If the user accepts delivery, all of the files
are moved into the current directory.
.PP
The third form of the command simply tells the user if there are any
files waiting.
.SH SEE ALSO
ftp(1c), rcp(1), finger(1)
SHAR_EOF
fi # end of overwriting check
# End of shell archive
exit 0
--
For comp.sources.unix stuff, mail to sources at uunet.uu.net.
More information about the Comp.sources.unix
mailing list