home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Beijing Paradise BBS Backup
/
PARADISE.ISO
/
software
/
BBSDOORW
/
UUPC11XS.ZIP
/
UUCP
/
UUCP.C
next >
Wrap
C/C++ Source or Header
|
1992-12-11
|
26KB
|
627 lines
/*--------------------------------------------------------------------*/
/* u u c p . c */
/* */
/* UUCP lookalike for IBM PC. */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* Changes Copyright (c) 1989 by Andrew H. Derbyshire. */
/* */
/* Changes Copyright (c) 1990-1992 by Kendra Electronic */
/* Wonderworks. */
/* */
/* All rights reserved except those explicitly granted by the */
/* UUPC/extended license agreement. */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* RCS Information */
/*--------------------------------------------------------------------*/
/*
* $Id: UUCP.C 1.2 1992/12/11 12:45:11 ahd Exp $
*
* Revision history:
* $Log: UUCP.C $
* Revision 1.2 1992/12/11 12:45:11 ahd
* Normalize paths for files read
*
*/
/*--------------------------------------------------------------------*/
/* */
/* Change history: */
/* */
/* 02/08/81 H.A.E.Broomhall */
/* Hacked for UUPC/extended 1.09c */
/* 04/27/91 Drew Derbyshire */
/* Modified for UUPC/extended 1.10a */
/* 09/26/91 Mitch Mitchell */
/* Support for UUX */
/* 01/26/92 Drew Derbyshire */
/* Various comment and error message clean up */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* system include files */
/*--------------------------------------------------------------------*/
#include <ctype.h>
#include <direct.h>
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
/*--------------------------------------------------------------------*/
/* UUPC/extended include files */
/*--------------------------------------------------------------------*/
#include "lib.h"
#include "expath.h"
#include "getopt.h"
#include "getseq.h"
#include "hlib.h"
#include "hostable.h"
#include "import.h"
#include "ndir.h"
#include "security.h"
#include "timestmp.h"
/*--------------------------------------------------------------------*/
/* Global variables */
/*--------------------------------------------------------------------*/
static boolean spool_flag = FALSE;
static char spool_file[FILENAME_MAX]; /* alt spool file name */
static boolean dir_flag = TRUE;
static boolean xeqt_flag = TRUE; /* Triggered by -r option */
static char grade = 'n'; /* Default grade of service */
static boolean mail_me = FALSE; /* changes with -m */
static boolean mail_them = FALSE; /* changes with -n */
static char remote_user[10]; /* user to mail with -n */
static char *destn_file;
static char flags[16];
currentfile();
/*--------------------------------------------------------------------*/
/* u s a g e */
/* */
/* Report flags used by program */
/*--------------------------------------------------------------------*/
static void usage(void)
{
fprintf(stderr, "Usage: uucp\t[-c|-C] [-d|-f] [-gGRADE] [-j] [-m] [-nUSER] [-r] [-sFILE]\\\n\
\t\t[-xDEBUG_LEVEL] source-files destination-file\n");
}
/*--------------------------------------------------------------------*/
/* c p */
/* */
/* Copy a file */
/*--------------------------------------------------------------------*/
static int cp(char *from, char *to)
{
int fd_from, fd_to;
int nr, nw = -1;
char buf[BUFSIZ*4]; /* faster if we alloc a big buffer */
if ((fd_from = open(from, O_RDONLY | O_BINARY)) == -1)
return(1); /* failed */
/* what if the to is a directory? */
/* possible with local source & dest uucp */
if ((fd_to = open(to, O_CREAT | O_BINARY | O_WRONLY, S_IWRITE | S_IREAD)) == -1) {
close(fd_from);
return(1); /* failed */
/* NOTE - this assumes all the required directories exist! */
}
while ((nr = read(fd_from, buf, sizeof buf)) > 0 &&
(nw = write(fd_to, buf, nr)) == nr)
;
close(fd_to);
close(fd_from);
if (nr != 0 || nw == -1)
return(1); /* failed in copy */
return(0);
} /* cp */
/*--------------------------------------------------------------------*/
/* s p l i t _ p a t h */
/* */
/* split_path splits a path into 3 components. */
/* 1) The system next in line */
/* 2) Any intermediate systems as a bang path */
/* 3) The actual file name/path */
/* */
/* It tries to be a little clever with idiots, in recognizing */
/* system=this machine */
/*--------------------------------------------------------------------*/
static void split_path(char *path,
char *system,
char *inter,
char *file)
{
char *p_left, *p_right, *p;
*system = *inter = *file = '\0'; /* init to nothing */
for (p = path;; p = p_left + 1) {
p_left = strchr(p, '!'); /* look for the first bang */
if (p_left == NULL) { /* not a remote path */
strcpy(file, p); /* so just return filename */
return;
}
/* now check if the system was in fact us.
If so strip it and restart */
if (equaln(E_nodename, p, p_left - p) &&
(E_nodename[p_left - p] == '\0'))
continue;
p_right = strrchr(p, '!'); /* look for the last bang */
strcpy(file, p_right + 1); /* and thats our filename */
strncpy(system, p, p_left - p); /* and we have a system thats not us */
system[p_left - p] = '\0';
/* now see if there is an intermediate path */
if (p_left != p_right) { /* yup - there is */
strncpy(inter, p_left + 1, p_right - p_left - 1);
inter[p_right - p_left - 1] = '\0';
}
return; /* and we're done */
} /* never get here :-) */
}
/*--------------------------------------------------------------------*/
/* d o _ u u x */
/* */
/* Generate & execute UUX command */
/*--------------------------------------------------------------------*/
int do_uux(char *remote,
char *src_syst,
char *src_file,
char *dest_syst,
char *dest_inter,
char *dest_file)
{
char xcmd[BUFSIZ]; /* buffer for assembling the UUX command */
char *ex_flg;
/*--------------------------------------------------------------------*/
/* First - lets get the basic command */
/*--------------------------------------------------------------------*/
ex_flg = xeqt_flag ? "" : "-r";
sprintf(xcmd, "uux -C %s %s!uucp -C ", ex_flg, remote);
/* but what about mailing the guy? */
/*--------------------------------------------------------------------*/
/* Now we sort out the source name */
/*--------------------------------------------------------------------*/
if ((*src_syst == '\0') || equal(src_syst, E_nodename))
sprintf(xcmd + strlen(xcmd), " \\!%s ", src_file);
else {
if (!equal(remote, src_syst))
sprintf(xcmd + strlen(xcmd), " (%s!%s) ", src_syst, src_file);
else
sprintf(xcmd + strlen(xcmd), " (%s) ", src_file);
} /* else */
/*--------------------------------------------------------------------*/
/* Now to do the destination name */
/*--------------------------------------------------------------------*/
if (*dest_inter != '\0') {
if (*dest_syst != '\0')
sprintf(xcmd + strlen(xcmd), " (%s!%s!%s) ", dest_syst, dest_inter, dest_file);
else
sprintf(xcmd + strlen(xcmd), " (%s!%s) ", dest_inter, dest_file);
}
else {
if ((*dest_syst == '\0') || equal(dest_syst, E_nodename))
sprintf(xcmd + strlen(xcmd), " (%s!%s) ", E_nodename, dest_file);
}
printmsg(2, "xcmd: %s", xcmd);
/*--------------------------------------------------------------------*/
/* OK - GO! */
/*--------------------------------------------------------------------*/
system(xcmd);
return(1);
} /* do_uux */
/*--------------------------------------------------------------------*/
/* d o _ c o p y */
/* */
/* At this point only one of the systems can be remote and only */
/* 1 hop away. All the rest have been filtered out */
/*--------------------------------------------------------------------*/
int do_copy(char *src_syst,
char *src_file,
char *dest_syst,
char *dest_file)
{
char *p;
boolean wild_flag = FALSE;
boolean write_flag;
char tmfile[15]; /* Unix style name for c file */
char idfile[15]; /* Unix style name for data file copy */
char work[FILENAME_MAX]; /* temp area for filename hacking */
char search_file[FILENAME_MAX];
char source_path[FILENAME_MAX];
char icfilename[FILENAME_MAX]; /* our hacked c file path */
char idfilename[FILENAME_MAX]; /* our hacked d file path */
struct stat statbuf;
DIR *dirp = NULL;
struct direct *dp = NULL;
char subseq = 'A';
long int sequence;
char *remote_syst; /* Non-local system in copy */
char *sequence_s;
FILE *cfile;
static char *spool_fmt = SPOOLFMT;
sequence = getseq();
sequence_s = JobNumber( sequence );
remote_syst = equal(src_syst, E_nodename) ? dest_syst : src_syst;
sprintf(tmfile, spool_fmt, 'C', remote_syst, grade, sequence_s);
importpath(work, tmfile, remote_syst);
mkfilename(icfilename, E_spooldir, work);
if (!equal(src_syst, E_nodename))
{
if (expand_path(dest_file, NULL, E_homedir, NULL) == NULL)
exit(1);
strcpy( dest_file, normalize( dest_file ));
p = src_file;
while (*p)
{
if (*p == '\\')
*p = '/';
p++;
}
printmsg(1, "uucp - from \"%s\" - control = %s", src_syst,
tmfile);
if ((cfile = FOPEN(icfilename, "a", TEXT )) == NULL) {
printerr( icfilename );
fprintf(stderr, "uucp: cannot append to %s\n", icfilename);
panic();
}
fprintf(cfile, "R %s %s %s -%s %s 0777 %s\n", src_file, dest_file,
E_mailbox, flags, *spool_file ? spool_file : "dummy", remote_user);
fclose(cfile);
return(1);
}
else if (!equal(dest_syst, E_nodename)) {
printmsg(1,"uucp - spool %s - mkdir %s - execute %s",
spool_flag ? "on" : "off",
dir_flag ? "on" : "off", xeqt_flag ? "do" : "don't");
printmsg(1," - dest m/c = %s sequence = %ld control = %s",
dest_syst, sequence, tmfile);
if (expand_path(src_file, NULL, E_homedir, NULL) == NULL)
exit(1);
normalize( src_file );
p = dest_file;
while (*p)
{
if (*p == '\\')
*p = '/';
p++;
}
if (strcspn(src_file, "*?") == strlen(src_file))
{
wild_flag = FALSE;
if (stat(src_file, &statbuf) != 0)
{
printerr( src_file );
exit(1);
}
if (statbuf.st_mode & S_IFDIR)
{
printf("uucp - directory name \"%s\" illegal\n",
src_file );
exit(1);
}
} /* if (strcspn(src_file, "*?") == strlen(src_file)) */
else {
wild_flag = TRUE;
strcpy(source_path, src_file);
p = strrchr(source_path, '/');
strcpy(search_file, p+1);
*++p = '\0';
dirp = opendirx(source_path,search_file);
if (dirp == NULL)
{
printf("uucp - unable to open directory %s\n",source_path);
exit(1);
} /* if */
if ((dp = readdir(dirp)) == nil(struct direct))
{
printf("uucp - can't find any file %s\n", search_file);
exit(1);
}
} /* else */
write_flag = TRUE;
while (write_flag)
{
if (wild_flag)
{
strcpy(src_file, source_path);
strlwr( dp->d_name );
strcat( strcpy(src_file, source_path), dp->d_name );
strcpy( src_file, normalize( src_file ));
printf("Queueing file %s for %s!%s\n", src_file, dest_syst,
dest_file);
}
if (spool_flag) {
sprintf(idfile , spool_fmt, 'D', E_nodename, (char) subseq++,
sequence_s);
importpath(work, idfile, remote_syst);
mkfilename(idfilename, E_spooldir, work);
/* Do we need a MKDIR here for the system? */
if (cp(src_file, idfilename) != 0) {
printmsg(0, "copy \"%s\" to \"%s\" failed",
src_file, idfilename); /* copy data */
closedir( dirp );
exit(1);
}
}
else
strcpy(idfile, "D.0");
if ((cfile = FOPEN(icfilename, "a", TEXT)) == NULL) {
printerr( icfilename );
printf("uucp: cannot append to %s\n", icfilename);
if (dirp != NULL )
closedir( dirp );
exit(1);
}
fprintf(cfile, "S %s %s %s -%s %s 0666 %s\n", src_file, dest_file,
E_mailbox, flags, idfile, remote_user);
fclose(cfile);
if (wild_flag) {
dp = readdir(dirp);
if ( dp == NULL )
write_flag = FALSE;
}
else
write_flag = FALSE;
}
if (dirp != NULL )
closedir( dirp );
return(1);
}
else {
if (expand_path(src_file, NULL, E_homedir, NULL) == NULL)
exit(1);
if (expand_path(dest_file, NULL, E_homedir, NULL) == NULL)
exit(1);
if (strcmp(src_file, dest_file) == 0)
{
fprintf(stderr, "%s %s - same file; can't copy\n",
src_file, dest_file);
exit(1);
}
cp(src_file, dest_file);
return(1);
}
}
/*--------------------------------------------------------------------*/
/* m a i n */
/* */
/* main program, of course */
/*--------------------------------------------------------------------*/
void main(int argc, char *argv[])
{
int i;
int option;
boolean j_flag = FALSE;
char src_system[100], dest_system[100];
char src_inter[100], dest_inter[100];
char src_file[FILENAME_MAX], dest_file[FILENAME_MAX];
/*--------------------------------------------------------------------*/
/* Initialize */
/*--------------------------------------------------------------------*/
debuglevel = 0;
banner( argv );
if (!configure(B_UUCP))
exit(1);
/*--------------------------------------------------------------------*/
/* Process option flags */
/*--------------------------------------------------------------------*/
while ((option = getopt(argc, argv, "Ccdfg:jmn:rs:x:")) != EOF) {
switch(option) {
case 'c': /* don't spool */
spool_flag = FALSE;
break;
case 'C': /* force spool */
spool_flag = TRUE;
break;
case 'd': /* make directories */
dir_flag = TRUE;
break;
case 'e': /* send uucp command to sys */
/* This one is in Sams but nowhere else - I'm ignoring it */
break;
case 'f': /* don't make directories */
dir_flag = FALSE;
break;
case 'g': /* set grade of transfer */
grade = *optarg;
break;
case 'j': /* output job id to stdout */
j_flag = TRUE;
break;
case 'm': /* send mail when copy completed */
mail_me = TRUE;
break;
case 'n': /* notify remote user file was sent */
mail_them = TRUE;
sprintf(remote_user, "%.8s", optarg);
break;
case 'r': /* queue job only */
xeqt_flag = FALSE;
break;
case 's': /* report status of transfer to file */
strcpy( spool_file, optarg);
expand_path( spool_file, NULL, E_pubdir , NULL);
break;
case 'x': /* set debug level */
debuglevel = atoi(optarg);
break;
default:
usage();
exit(1);
break;
}
}
flags[0] = (char)(dir_flag ? 'd' : 'f');
flags[1] = (char)(spool_flag ? 'C' : 'c');
i = 2;
if (mail_them)
flags[i++] = 'n';
flags[i] = '\0';
if (remote_user[0] == '\0')
strcpy(remote_user, E_mailbox);
if (argc - optind < 2) {
usage();
exit(1);
}
/*--------------------------------------------------------------------*/
/* Now - posibilities: */
/* Sources - 1 or more, local or 1 hop away (NOT > 1 hop!) */
/* Dest - normal cp rules, single only, local, 1 hop or >1 */
/* hop */
/* Wildcards possible on sources. */
/* */
/* Actions depend on these - so we need to split the pathnames */
/* for more info. */
/*--------------------------------------------------------------------*/
split_path(argv[argc - 1], dest_system, dest_inter, dest_file);
/*--------------------------------------------------------------------*/
/* OK - we have a destination system - do we know him? */
/*--------------------------------------------------------------------*/
if (*dest_system != '\0') {
if (checkreal(dest_system) == BADHOST) {
fprintf(stderr, "uucp - bad system: %s\n", dest_system);
exit(1);
}
}
else /* make sure we have a system name for destination */
strcpy(dest_system, E_nodename);
printmsg(9, "destination: system \"%s\", inter \"%s\", file \"%s\"",
dest_system, dest_inter, dest_file);
/*--------------------------------------------------------------------*/
/* Now - if there is more than 1 source then normal cp rules, */
/* i.e. dest must be a directory */
/*--------------------------------------------------------------------*/
if (argc - optind > 2)
strcat(dest_file, "/");
destn_file = argv[argc - 1];
for (i = optind; i < (argc - 1); i++) {
split_path(argv[i], src_system, src_inter, src_file);
/*--------------------------------------------------------------------*/
/* We need to winnow out various combinations - */
/* so lets get at them */
/* */
/* Do we know the source system? */
/*--------------------------------------------------------------------*/
if (*src_system != '\0') {
if (checkreal(src_system) == BADHOST) {
fprintf(stderr, "uucp - bad system %s\n", src_system);
exit(1);
}
}
/*--------------------------------------------------------------------*/
/* Source can't be >1 hop away */
/*--------------------------------------------------------------------*/
if (*src_inter != '\0') {
fprintf(stderr, "uucp - illegal syntax %s\n", argv[i]);
exit(1);
}
/*--------------------------------------------------------------------*/
/* if source is remote AND wildcarded then we need uux */
/*--------------------------------------------------------------------*/
if ((*src_system != '\0') && (strcspn(src_file, "*?[") < strlen(src_file))) {
do_uux(src_system, src_system, src_file, dest_system, dest_inter, dest_file);
continue;
}
/*--------------------------------------------------------------------*/
/* if dest requires forwarding then we need uux */
/*--------------------------------------------------------------------*/
if (*dest_inter != '\0') {
do_uux(dest_system, src_system, src_file, "", dest_inter, dest_file);
continue;
}
/*--------------------------------------------------------------------*/
/* if both source & dest are remote then we need uux */
/*--------------------------------------------------------------------*/
if ((*src_system != '\0') && (!equal(src_system, E_nodename)) &&
(*dest_system != '\0') && (!equal(dest_system, E_nodename))) {
do_uux(dest_system, src_system, src_file, "", dest_inter, dest_file);
continue;
}
/*--------------------------------------------------------------------*/
/* We have left 3 options: */
/* 1) src remote (non-wild) & dest local */
/* 2) src local & dest remote 1 hop */
/* 3) src & dest both local */
/* */
/* fill up the src system if not already */
/*--------------------------------------------------------------------*/
if (*src_system == '\0')
strcpy(src_system, E_nodename);
printmsg(4, "source: system \"%s\", file \"%s\"", src_system,
src_file);
do_copy(src_system, src_file, dest_system, dest_file);
}
if (xeqt_flag)
printmsg(1, "Call uucico");
if (j_flag)
printmsg(1,"j_flag");
exit(0);
}