📄 uux.c
字号:
/*--------------------------------------------------------------------*/
/* u u x . c */
/* */
/* Queue remote commands for UUCP under UUPC/extended */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* Changes Copyright (c) 1989-1993 by Kendra Electronic */
/* Wonderworks. */
/* */
/* All rights reserved except those explicitly granted by */
/* the UUPC/extended license agreement. */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* RCS Information */
/*--------------------------------------------------------------------*/
/*
* $Id: uux.c 1.8 1993/10/03 20:43:08 ahd Exp $
*
* Revision history:
* $Log: uux.c $
* Revision 1.8 1993/10/03 20:43:08 ahd
* Normalize comments to C++ double slash
*
* Revision 1.7 1993/10/01 01:17:44 ahd
* Additional correct from Richard Gumpertz
*
* Revision 1.6 1993/09/28 01:38:19 ahd
* Corrections from Robert H. Gumpertz (rhg@cps.com)
*
* Revision 1.5 1993/09/20 04:48:25 ahd
* TCP/IP support from Dave Watt
* 't' protocol support
* OS/2 2.x support (BC++ 1.0 for OS/2)
*
*/
/*
Program: uux.c 27 August 1991
Author: Mitch Mitchell
Email: mitch@harlie.lonestar.org
Much of this code is shamelessly taken from extant code in
UUPC/Extended.
Usage: uux [ options ] command-string
Where [ options ] are:
-aname Use name as the user identification replacing the initiator
user-id. (Notification will be returned to the user.)
-b Return whatever standard input was provided to the uux command
if the exit status is non-zero.
-c Do not copy local file to the spool directory for transfer to
the remote machine (default).
-C Force the copy of local files to the spool directory for
transfer.
-e Remote system should use sh to execute commands.
-E Remote system should use exec to execute commands.
-ggrade Grade is a single letter/number; lower ASCII sequence
characters will cause the job to be transmitted earlier during
a particular conversation.
-j Output the jobid ASCII string on the standard output which is
the job identification. This job identification can be used by
uustat to obtain the status or terminate a job.
-n Do not notify the user if the command fails.
-p The standard input to uux is made the standard input to the
command-string.
-r Do not start the file transfer, just queue the job.
(Currently uux does not attempt to start the transfer
regardless of the presense of this option).
-sfile Report status of the transfer in file.
-xdebug_level
Produce debugging output on the standard output. The
debug_level is a number between 0 and ??; higher numbers give
more detailed information.
-z Send success notification to the user.
The command-string is made up of one or more arguments that
look like a normal command line, except that the command and
filenames may be prefixed by system-name!. A null
system-name is interpreted as the local system.
*/
/*--------------------------------------------------------------------*/
/* System include files */
/*--------------------------------------------------------------------*/
#include <stdio.h>
#include <io.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef _Windows
#include <windows.h>
#endif
/*--------------------------------------------------------------------*/
/* Local include files */
/*--------------------------------------------------------------------*/
#include "lib.h"
#include "hlib.h"
#include "getopt.h"
#include "getseq.h"
#include "expath.h"
#include "import.h"
#include "pushpop.h"
#include "security.h"
#include "hostable.h"
#include "timestmp.h"
#ifdef _Windows
#include "winutil.h"
#include "logger.h"
#endif
/*--------------------------------------------------------------------*/
/* Define current file name for panic() and printerr() */
/*--------------------------------------------------------------------*/
currentfile();
/*--------------------------------------------------------------------*/
/* Global variables */
/*--------------------------------------------------------------------*/
typedef enum {
FLG_USE_USERID,
FLG_OUTPUT_JOBID,
FLG_READ_STDIN,
FLG_QUEUE_ONLY,
FLG_NOTIFY_SUCCESS,
FLG_NONOTIFY_FAIL,
FLG_COPY_SPOOL,
FLG_RETURN_STDIN,
FLG_STATUS_FILE,
FLG_USE_EXEC,
FLG_MAXIMUM
} UuxFlags;
typedef enum {
DATA_FILE = 0, // Normal data file passed argument
INPUT_FILE = 1, // Redirected stdin file
OUTPUT_FILE = 2 // Redirected stdout file
} FileType;
static boolean flags[FLG_MAXIMUM] = {
FALSE,
FALSE,
FALSE,
FALSE,
FALSE,
FALSE,
FALSE,
FALSE,
FALSE,
FALSE
};
static char* st_out = NULL;
static char* user_id = NULL;
static char grade = 'Z'; // Default grade of service
static char job_id[15];
static char* spool_fmt = SPOOLFMT;
static char* dataf_fmt = DATAFFMT;
static char* send_cmd = "S %s %s %s - %s 0666\n";
/*--------------------------------------------------------------------*/
/* Internal prototypes */
/*--------------------------------------------------------------------*/
void main(int argc, char **argv);
static void usage( void );
static char *SwapSlash(char *p);
static boolean cp(char *from, char *to);
static boolean split_path(char *path,
char *system,
char *file,
boolean expand,
char *default_sys);
static boolean CopyData( const char *input, const char *output);
static boolean do_uuxqt(char *job_name, char *src_syst, char *src_file, char *dest_syst, char *dest_file);
static boolean do_copy(char *src_syst, char *src_file, char *dest_syst, char *dest_file);
static boolean do_remote(int optind, int argc, char **argv);
static void preamble(FILE* stream);
static char subseq( void );
/*--------------------------------------------------------------------*/
/* u s a g e */
/* */
/* Report flags used by program */
/*--------------------------------------------------------------------*/
static void usage()
{
fprintf(stderr, "Usage: uux\t[-c|-C] [-e|-E] [-b] [-gGRADE] "
"[-p] [-j] [-n] [-r] [-sFILE]\\\n"
"\t\t[-aNAME] [-z] [-] [-xDEBUG_LEVEL] "
"command-string\n");
}
/*--------------------------------------------------------------------*/
/* s w a p s l a s h */
/* */
/* Change backslash in a directory path to forward slash */
/*--------------------------------------------------------------------*/
static char *SwapSlash(char *p)
{
char *q = p;
while (*q) {
if (*q == '\\')
*q = '/';
q++;
}
return p;
};
/*--------------------------------------------------------------------*/
/* c p */
/* */
/* Copy Local Files */
/*--------------------------------------------------------------------*/
static boolean cp(char *from, char *to)
{
int fd_from, fd_to;
int nr;
int nw = -1;
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 FALSE; // 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 FALSE; // 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 FALSE; // failed in copy
return TRUE;
}
/*--------------------------------------------------------------------*/
/* C o p y D a t a */
/* */
/* Copy data into its final resting spot */
/*--------------------------------------------------------------------*/
static boolean CopyData( const char *input, const char *output)
{
FILE *datain;
FILE *dataout;
char buf[BUFSIZ];
boolean status = TRUE;
size_t len;
if ( (dataout = FOPEN(output, "w", BINARY_MODE)) == NULL )
{
printerr(output);
printmsg(0,"uux: Cannot open spool file \"%s\" for output",
output);
return FALSE;
}
/*--------------------------------------------------------------------*/
/* Verify the input opened */
/*--------------------------------------------------------------------*/
if (input == NULL)
{
datain = stdin;
setmode(fileno(datain), O_BINARY); // Don't die on control-Z, etc
}
else
datain = FOPEN(input, "r", BINARY_MODE);
if (datain == NULL) {
printerr(input);
printmsg(0,"Unable to open input file \"%s\"",
(input == NULL ? "stdin" : input));
fclose(dataout);
return FALSE;
} /* datain */
/*--------------------------------------------------------------------*/
/* Loop to copy the data */
/*--------------------------------------------------------------------*/
while ( (len = fread( buf, 1, BUFSIZ, datain)) != 0)
{
if ( fwrite( buf, 1, len, dataout ) != len) // I/O error?
{
printerr("dataout");
printmsg(0,"I/O error on \"%s\"", output);
fclose(dataout);
return FALSE;
} /* if */
} /* while */
/*--------------------------------------------------------------------*/
/* Close up shop and return */
/*--------------------------------------------------------------------*/
if (ferror(datain)) // Clean end of file on input?
{
printerr(input);
clearerr(datain);
status = FALSE;
}
if (input != NULL)
fclose(datain);
fclose(dataout);
return status;
} /* CopyData */
/*--------------------------------------------------------------------*/
/* s p l i t _ p a t h */
/*--------------------------------------------------------------------*/
static boolean split_path(char *path,
char *sysname,
char *file,
boolean expand,
char *default_sys )
{
char *p_left;
char *p_right;
char *p = path;
*sysname = *file = '\0'; // init to nothing
/*--------------------------------------------------------------------*/
/* if path is wildcarded then error */
/*--------------------------------------------------------------------*/
if (strcspn(path, "*?[") < strlen(path))
{
printmsg(0,"uux - Wildcards not allowed in operand: %s",p );
return FALSE;
}
/*--------------------------------------------------------------------*/
/* Find the first bangs */
/*--------------------------------------------------------------------*/
p_left = strchr(p, '!'); // look for the first bang
/*--------------------------------------------------------------------*/
/* If no bangs, then the file is on the remote system. We hope. */
/*--------------------------------------------------------------------*/
if ( p_left == NULL )
{
strcpy( file, p); // Entire string is file name
strcpy( sysname, default_sys ); // Use default system name
if ( equal(sysname, E_nodename ) &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -