/* * uux.c: Very simple uux for smail * * Stephen Trier * March 28, 1990 * * This uux is just barely smart enough to get the mail through. * It should work for rnews, but provisions will have to be added * to change the file owner from uucp to news. * * This program is in the public domain. * * Patch 1 written 5/23/90 by Stephen Trier: Change the definition * of localname to avoid short host name bug. This way, both * uuio and uux will use the same filenames. * */ #include #include #include #include "config.h" /* Array of filenames for easier code reading. */ enum filetype { CALL, DATA, XQT }; enum nametype { FAKE, /* "Fake" names: what we call the file */ LOCAL, /* "Local" names: what we _claim_ is the filename */ REMOTE /* "Remote" names: the names given once sent */ }; char fn[3][3][80]; /* char filename [filetype][nametype][80] */ char *remotename; /* Name of where we're calling */ char cmd[128]; /* Command to execute there */ /* * ms_config: Load configuration information */ char *ms_libdir = "\\usr\\lib", *ms_spool = "\\usr\\spool\\uucp", *localname = "invalid"; static struct table_entry table[] = { "confdir", &ms_libdir, "spooldir", &ms_spool, "nodename", &localname, NULL } ; /* * error: Print error message and terminate */ void error(char *s) /* Does not return! */ { fprintf(stderr, s); perror("uux"); exit(1); } /* * check_names: Check the remote system name against the systems file */ void check_name(void) /* Does not return if invalid name */ { FILE *fp; char filename[80]; char name[80]; sprintf(filename, "%s/systems", ms_libdir); if ((fp = fopen(filename, "r")) == NULL) error("uux: Can't open systems file.\n"); while (!feof(fp)) { fscanf(fp, "%[^ \n\t]%*[^\n] ", name); if (strcmp(name, remotename) == 0) { fclose(fp); return; } } fclose(fp); fprintf(stderr, "uux: Can't connect to remote system %s\n", remotename); exit(2); } /* * find_params: Build the parameter list for the command */ void find_params(char **argv) { char *tmp; while (*argv != NULL) { for (tmp = *argv; ; ) if (*tmp == '\'') { *(strrchr(tmp, '\'')) = '\0'; tmp++; } else if (*tmp == '(') { *(strrchr(tmp, ')')) = '\0'; tmp++; } else break; strcat(cmd, " "); strcat(cmd, tmp); argv++; } } /* * make_filenames: Put together all of the filenames needed */ int get_sequence(void) { char filename[80]; FILE *fp; int sequence = 0; sprintf(filename, "%s/seqf", ms_libdir); if ((fp = fopen(filename, "r+")) == NULL) { if ((fp = fopen(filename, "w")) == NULL) error("uux: Can't open sequence file\n"); } else { fscanf(fp, "%d", &sequence); rewind(fp); sequence %= 1000; } fprintf(fp, "%3.3d", (sequence+1) % 1000); fclose(fp); return sequence; } /* Templates for filenames. P=path, C=character, S=system, N=seq. number */ #define LOCALNAME(P,C,S,N) "%s/%c_%s%04.4d.%03.3d",P,C,S,N,N #define REMOTENAME(C,S,N) "%c.%.7s%04d",C,S,N void make_filenames(void) { int sequence; /* Get sequence number */ sequence = get_sequence(); /* Make filenames */ sprintf(fn[CALL][FAKE], LOCALNAME(ms_spool, 'C', remotename, sequence)); sprintf(fn[DATA][FAKE], LOCALNAME(ms_spool, 'D', remotename, sequence)); sprintf(fn[DATA][LOCAL], REMOTENAME('D', remotename, sequence)); sprintf(fn[DATA][REMOTE], REMOTENAME('D', localname, sequence)); sprintf(fn[XQT][FAKE], LOCALNAME(ms_spool, 'D', localname, sequence)); sprintf(fn[XQT][LOCAL], REMOTENAME('D', localname, sequence)); sprintf(fn[XQT][REMOTE], REMOTENAME('X', localname, sequence)); } /* * make_data, make_call, make_xqt: Output the files */ void make_data(void) { FILE *fp; char buf[80]; if ((fp = fopen(fn[DATA][FAKE], "wb")) == NULL) error("uux: Can't open data spool file\n"); while (fgets(buf, 80, stdin) != NULL) fputs(buf, fp); fclose(fp); } void make_call(void) { FILE *fp; if ((fp = fopen(fn[CALL][FAKE], "wb")) == NULL) error("uux: Can't open call file\n"); fprintf(fp, "S %s %s uucp - %s 0666 uucp\n", fn[DATA][LOCAL], fn[DATA][REMOTE], fn[DATA][REMOTE]); fprintf(fp, "S %s %s uucp - %s 0666 uucp\n", fn[XQT][LOCAL], fn[XQT][REMOTE], fn[XQT][REMOTE]); fclose(fp); } void make_xqt(void) { FILE *fp; if ((fp = fopen(fn[XQT][FAKE], "wb")) == NULL) error("uux: Can't open xqt control file\n"); fprintf(fp, "U uucp %s\n", localname); fprintf(fp, "I %s\n", fn[DATA][REMOTE]); fprintf(fp, "F %s\n", fn[DATA][REMOTE]); fprintf(fp, "C %s\n", cmd); fclose(fp); } /* * main: Parse command line and set up */ main(int argc, char *argv[]) { char *tmp; /* Read in the user configurations */ ms_config(table); /* Parse arguments */ argv++; while ((*argv != NULL) && (**argv == '-')) argv++; if (*argv == NULL) error("uux: Illegal command line\n"); /* Get the name of the target system */ remotename = *argv; if ((tmp = strchr(*argv, '!')) == NULL) error("uux: Can't find remote system name\n"); *(tmp++) = '\0'; strcpy(cmd, tmp); /* Check that system's name for validity */ check_name(); /* Figure out the command options */ find_params(++argv); /* Put together our filenames */ make_filenames(); /* Output the files */ make_data(); make_call(); make_xqt(); return 0; /* All went well */ }