home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************
- *@(#) uucp.c UUCP lookalike for IBM PC.
- * H.A.E.Broomhall 1991/02/08
- * Hacked for UUPC/extended 1.09c
- * Modified for UUPC/extended 1.10a by ahd 4/27/91
- * Support for UUX by Mitch Mitchell 9/26/91
- *******************************************************/
-
- /*--------------------------------------------------------------------*/
- /* 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");
- }
-
- static int cp(char *from, char *to)
- {
- int fd_from, fd_to;
- int nr, nw;
- char buf[BUFSIZ]; /* faster if we alloc a big buffer */
-
- /* This would be even faster if we determined that both files
- were on the same device, dos >= 3.0, and used the dos move
- function */
- 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);
- }
-
- /*--------------------------------------------------------------------*/
- /* 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(nodename, p, p_left - p) && (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, 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);
- }
- /* 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, nodename))
- sprintf(xcmd + strlen(xcmd), " (%s!%s) ", nodename, dest_file);
- }
- printmsg(2, "xcmd: %s", xcmd);
- /* OK - GO! */
- system(xcmd);
- return(1);
- }
-
- /*--------------------------------------------------------------------*/
- /* 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, *p1;
- 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[66]; /* temp area for filename hacking */
- char search_file[66];
- char source_path[66];
- char icfilename[66]; /* our hacked c file path */
- char idfilename[66]; /* our hacked d file path */
-
- struct stat statbuf;
- DIR *dirp = NULL;
- struct direct *dp;
- 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, nodename) ? dest_syst : src_syst;
- sprintf(tmfile, spool_fmt, 'C', remote_syst, grade, sequence_s);
- importpath(work, tmfile, remote_syst);
- mkfilename(icfilename, spooldir, work);
-
- if (!equal(src_syst, nodename)) {
- if (expand_path(dest_file, NULL, homedir, NULL) == NULL)
- exit(1);
- p = src_file;
- while (*p) {
- if (*p == '\\')
- *p = '/';
- p++;
- }
- printmsg(1, "uucp - from \"%s\" - control = %s", src_syst,
- tmfile);
- if ((cfile = FOPEN(icfilename, "a", 't')) == 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,
- mailbox, flags, *spool_file ? spool_file : "dummy", remote_user);
- fclose(cfile);
- return(1);
- }
- else if (!equal(dest_syst, 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, homedir, NULL) == NULL)
- exit(1);
- 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);
- }
- }
- 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);
- }
- }
- write_flag = TRUE;
- while (write_flag) {
- if (wild_flag) {
- strcpy(src_file, source_path);
- p = strchr(src_file, '\0');
- p1 = dp->d_name;
- while (*p1)
- *p++ = (char)tolower(*p1++);
- *p = '\0';
- printf("Queueing file %s for %s!%s\n", src_file, dest_syst,
- dest_file);
- }
- if (spool_flag) {
- sprintf(idfile , spool_fmt, 'D', nodename, (char) subseq++,
- sequence_s);
- importpath(work, idfile, remote_syst);
- mkfilename(idfilename, 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", 't')) == 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,
- 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, homedir, NULL) == NULL)
- exit(1);
- if (expand_path(dest_file, NULL, 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 s_remote = FALSE;
- boolean d_remote = FALSE;
- */
- 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, 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, 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, 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, nodename)) &&
- (*dest_system != '\0') && (!equal(dest_system, 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, 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);
- }
-