home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************
- * *
- * Background File Transfer Program (BFTP) *
- * *
- * Written at USC/Information Sciences Institute *
- * September, 1988 *
- * *
- * BFTP is Public Domain, and may be used for any purpose as *
- * long as this notice is not removed. USC-ISI does not assume *
- * any responsibility for the correctness, performance, or use *
- * of this software. *
- * *
- ************************************************************************/
-
- /*
- * bftp.c
- *
- * The "bftp" tty-style user interface, is implemented in this module.
- *
- */
-
- #include <stdio.h>
- #include <signal.h>
- #include <ctype.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/param.h>
- #include <sys/file.h>
- #include <netinet/in.h>
-
- #ifdef ISI4_2
- #include <netdb.h-bind>
- #else
- #include <netdb.h>
- #endif
-
- #include <time.h>
- #include "bftp.h"
- #include "ucb_cp.h"
-
- extern char
- *get_request_file(),
- *introduction,
- *version,
- *background;
- extern boolean
- parse_date(),
- read_req(),
- write_req(),
- queue_req(),
- print_req();
- extern char
- *expand_stru(),
- *expand_mode(),
- **get_save_files();
-
- extern void
- format_time(),
- close_listp(),
- redisplay(),
- unpack_filetype(),
- init_user(),
- init_req();
-
- extern int
- resolve_name();
-
- extern char
- bftp_dir[MAXPATHLEN],
- def_user[20],
- def_mailbox[101],
- def_hostname[80];
-
- extern struct hostinfo src, dst;
- extern struct fileinfo fil;
- extern struct reqinfo nullreq;
-
- extern u_long start;
-
- static struct reqinfo req;
- u_long local_addr;
- int
- verbose = FALSE;
- type = ASCII, /* Ascii plus form, Ebcdic plus form,
- (form = Non-print, Telnet, or Carriage-control)
- Image, or Local plus Byte-size */
- bytesiz = DEFAULT_BYTESZ,
- form = NONPRINT;
-
- int s, ns, len; /* socket stuff */
- struct sockaddr_in sin, from;
-
- #define p_prompt(str) if (str) printf(" %s ", str)
- #define p_help(str) if (str) printf("?%s\n", str)
-
- char *help_preamble =
- " Type 'help-all' for description of commands\n\
- 'explain' for detailed explanation\n\
- 'simple-example' for example using 'prompt'\n\n\
- Commands may be abbreviated; arguments may appear on the command line.\n\
- Type <control-C> to exit a command and display the BFTP prompt.\n\n";
-
- char *explanation1 =
- "To have the BFTP program prompt you for file transfer parameters, such as\n\
- host names, logins, and file names, enter the 'prompt' command. Use the\n\
- 'show' command to display the current request, and the 'init' command to\n\
- reset all of the parameters to their default values.\n\
- \n\
- The 'verify' command tells the BFTP server to connect to the specified hosts\n\
- (while you wait) to determine whether the parameters to be used in the\n\
- transfer are supported. Use the 'submit' command to transfer the file in\n\
- background mode. The 'transfer' command performs the file transfer while\n\
- you wait, rather than in the background.\n\
- \n\
- The 'find' command can be used to locate and display a request that is\n\
- waiting to be run. Once a request is displayed, it can be changed and\n\
- resubmited, or cancelled.\n\
- \n\
- Commands may be abreviated, and arguments may be entered, separated by\n\
- spaces, on the command line. For most fields, typing '?' <return> displays\n\
- a description of the argument that is to be entered. Use <control-C> to\n\
- abort a command and return to the BFTP prompt, and use the 'quit' command\n\
- to exit the BFTP program.\n";
-
- char *explanation2 =
- "\n\
- The commands, 'r-list', 'r-load', 'r-store', and 'r-delete', are used to list\n\
- requests that have been stored in file, to read a file in as the current\n\
- request, to save a request in a file, and to delete a request file.\n\
- \n\
- The remainder of the commands are used to change individual parameters.\n\
- When one is submitting more than one file transfer request, these commands\n\
- can be used to change specific parameters, such as the source file name\n\
- (using 's-file') and the destination file name (using 'd-file'). This may\n\
- be easier than repeating the whole 'prompt' sequence.\n";
-
- char *terminology =
- "\n\
- Additional BFTP terminology:\n\
- The 'mailbox' is the address where the report on the outcome of the\n\
- transfer will be sent.\n\
- The 'request keyword' will be checked if you should want to find out\n\
- the status of a request in the future, and/or cancel it. The\n\
- keyword is made up by the user and entered when the request is\n\
- submitted. It may be left blank if no checking is required.\n\
- The 'multiple' flag specifies that the wildcard character '*' will be\n\
- used to match multiple source file names.\n\
- The 'append' flag specifies that the file should be appended to an\n\
- existing file, rather than copied to a new file.\n\
- The 'unique' flag specifies that the STOU command will be used to store\n\
- the file. If this command is supported by the receiving host, it\n\
- will cause a unique file name to be created.\n\
- The 'StartTime', entered when a file is submitted or via the 'time'\n\
- command, is the time that the transfer will be attempted for the first\n\
- time. The 'interval' command sets how often the transfer will be\n\
- retried (in minutes), and the maximum number of tries. Each time that\n\
- a transfer is retried, the retry interval will be doubled, up to a\n\
- maximum of 4 hours.\n\
- ";
-
- boolean
- get_cr()
- {
- l1: printf("\nType <CR> for more help; type <control-C> for BFTP prompt: ");
- (void) gets(line);
- makeargv();
- if (margc && margv[0][0] == '?') {
- printf("Type <CR> to confirm.\n");
- goto l1;
- }
- if (margc)
- return(FALSE);
- else
- return(TRUE);
- } /* get_cr */
-
- boolean
- set_boolean(argc, argv, prompt, helpstr)
- int argc;
- char *argv[];
- char *prompt, *helpstr;
- {
- int len;
-
- if (argc < 1) {
- l1: p_prompt(prompt);
- (void) gets(line);
- makeargv();
- argc = margc;
- argv = margv;
- if (argc < 1) {
- p_help(helpstr);
- goto l1;
- }
- }
-
- len = strlen(argv[0]);
- if (!strncmp(argv[0], "true", len?len:1))
- return(TRUE);
- else if (!strncmp(argv[0], "false", len?len:1))
- return(FALSE);
- else if (!strncmp(argv[0], "yes", len?len:1))
- return(TRUE);
- else if (!strncmp(argv[0], "no", len?len:1))
- return(FALSE);
- else {
- p_help(helpstr);
- goto l1;
- }
- } /* set_boolean */
-
- set_form(argc, argv, prompt, helpstr)
- int argc;
- char *argv[];
- char *prompt, *helpstr;
- {
- int len;
-
- if (argc < 1) {
- l1: p_prompt(prompt);
- (void) gets(line);
- makeargv();
- argc = margc;
- argv = margv;
- if (argc < 1) {
- p_help(helpstr);
- goto l1;
- }
- }
-
- len = strlen(argv[0]);
- if (!strncmp(argv[0], "nonprint", len?len:1))
- form = NONPRINT;
- else if (!strncmp(argv[0], "telnet", len?len:1))
- form = TELNET;
- else if (!strncmp(argv[0], "carriage-control", len?len:1))
- form = CCNTRL;
- else {
- p_help(helpstr);
- goto l1;
- }
- } /* set_form */
-
- int
- set_host(argc, argv, prompt, helpstr, result)
- int argc;
- char *argv[];
- char *prompt, *helpstr, *result;
- {
- char temp[80];
- u_long inaddr;
-
- if (argc < 1) {
- l1: p_prompt(prompt);
- (void) gets(line);
- makeargv();
- argc = margc;
- argv = margv;
- }
- if (argc)
- strcpy(temp, argv[0]);
- else if (strlen(def_hostname))
- strcpy(temp, def_hostname);
- else {
- p_help(helpstr);
- goto l1;
- }
-
- if (resolve_name(temp, &inaddr, 1)) {
- if (result) strcpy(result, temp);
- }
- else {
- p_help(helpstr);
- goto l1;
- }
- } /* set_host */
-
- set_mbox(argc, argv, prompt, helpstr)
- int argc;
- char *argv[];
- char *prompt, *helpstr;
- {
- char temp[80], errorstr[40];
-
- if (argc < 1) {
- l1: p_prompt(prompt);
- (void) gets(line);
- makeargv();
- argc = margc;
- argv = margv;
- }
- if (argc)
- strcpy(temp, argv[0]);
- else if (strlen(def_mailbox))
- strcpy(temp, def_mailbox);
- else {
- p_help(helpstr);
- goto l1;
- }
-
- if (!mailbox_ok(temp, errorstr)) {
- errorstr[strlen(errorstr)-1] = '\0';
- p_help(errorstr);
- p_help(helpstr);
- goto l1;
- }
- else
- strcpy(req.mailbox, temp);
- } /* set_mbox */
-
- set_mode(argc, argv, prompt, helpstr)
- int argc;
- char *argv[];
- char *prompt, *helpstr;
- {
- int len;
-
- if (argc < 1) {
- l1: p_prompt(prompt);
- (void) gets(line);
- makeargv();
- argc = margc;
- argv = margv;
- if (argc < 1) {
- p_help(helpstr);
- goto l1;
- }
- }
-
- len = strlen(argv[0]);
- if (!strncmp(argv[0], "stream", len?len:1))
- fil.mode = 'S';
- else if (!strncmp(argv[0], "block", len?len:1))
- fil.mode = 'B';
- else if (!strncmp(argv[0], "compressed", len?len:1))
- fil.mode = 'C';
- else {
- p_help(helpstr);
- goto l1;
- }
- } /* set_mode */
-
- int
- check_number(arg)
- char *arg;
- {
- int num;
- char *cp;
-
- for (cp = arg; *cp; cp++)
- if (! isdigit(*cp))
- return(-1);
- num = atoi(arg);
- return(num);
- } /* check_number */
-
- set_number(argc, argv, prompt, helpstr, result)
- int argc;
- char *argv[];
- char *prompt, *helpstr;
- int *result;
- {
- int temp;
-
- if (argc < 1) {
- l1: p_prompt(prompt);
- (void) gets(line);
- makeargv();
- argc = margc;
- argv = margv;
- if (argc < 1) {
- p_help(helpstr);
- goto l1;
- }
- }
-
- if ((temp = check_number(argv[0])) > 0)
- *result = temp;
- else {
- p_help(helpstr);
- goto l1;
- }
- } /* set_number */
-
- set_string(argc, argv, prompt, helpstr, result)
- int argc;
- char *argv[];
- char *prompt, *helpstr, *result;
- {
- if (argc < 1) {
- l1: p_prompt(prompt);
- (void) gets(line);
- makeargv();
- argc = margc;
- argv = margv;
- }
- if (argc && argv[0][0] == '?') {
- printf("Type <CR> to blank field.\n%s%s\n",
- (helpstr)?"?":NULLSTR, (helpstr)?helpstr:NULLSTR);
- goto l1;
- }
-
- if (result) strcpy(result, (argc)?argv[0]:NULLSTR);
- } /* set_string */
-
- set_stru(argc, argv, prompt, helpstr)
- int argc;
- char *argv[];
- char *prompt, *helpstr;
- {
- int len;
-
- if (argc < 1) {
- l1: p_prompt(prompt);
- (void) gets(line);
- makeargv();
- argc = margc;
- argv = margv;
- if (argc < 1) {
- p_help(helpstr);
- goto l1;
- }
- }
-
- len = strlen(argv[0]);
- if (!strncmp(argv[0], "file", len?len:1))
- fil.stru = 'F';
- else if (!strncmp(argv[0], "page", len?len:1))
- fil.stru = 'P';
- else if (!strncmp(argv[0], "record", len?len:1))
- fil.stru = 'R';
- else {
- p_help(helpstr);
- goto l1;
- }
-
- if (fil.stru =='P') {
- fil.mode = 'S';
- strcpy(fil.filetype, "L 36");
- printf("Setting mode = 'stream'; type = 'local 36'.\n");
- }
- } /* set_stru */
-
- set_time(argc, argv, prompt, helpstr, def)
- int argc;
- char *argv[];
- char *prompt, *helpstr;
- time_t def;
- {
- int i;
- time_t date;
- char temp[80];
-
- if (argc > 0) {
- /* reconstruct the command line */
- temp[0] = '\0';
- for (i = argc; i; i--) {
- strcat(temp, argv[argc-i]);
- strcat(temp, " ");
- }
- }
- else {
- l1: p_prompt(prompt);
- (void) gets(line);
- strcpy(temp, line);
- makeargv();
- argc = margc;
- argv = margv;
- }
- if (argc && argv[0][0] == '?') {
- p_help(helpstr);
- goto l1;
- }
-
- if (!strlen(temp))
- start = (def > time(NULL))? def: 0;
- else if (parse_date(temp, &date))
- start = (date>time(NULL))? date: 0;
- else {
- p_help(helpstr);
- goto l1;
- }
- } /* set_time */
-
- set_tmode(argc, argv, prompt, helpstr)
- int argc;
- char *argv[];
- char *prompt, *helpstr;
- {
- int len;
-
- if (argc < 1) {
- l1: p_prompt(prompt);
- (void) gets(line);
- makeargv();
- argc = margc;
- argv = margv;
- if (argc < 1) {
- p_help(helpstr);
- goto l1;
- }
- }
-
- len = strlen(argv[0]);
- if (!strncmp(argv[0], "copy", len?len:1))
- fil.reqtype = COPY;
- else if (!strncmp(argv[0], "move", len?len:1))
- fil.reqtype = MOVE;
- else if (!strncmp(argv[0], "delete", len?len:1))
- fil.reqtype = DFILE;
- else {
- p_help(helpstr);
- goto l1;
- }
- } /* set_tmode */
-
- set_type(argc, argv, prompt, helpstr)
- int argc;
- char *argv[];
- char *prompt, *helpstr;
- {
- int len;
-
- if (argc < 1) {
- l1: p_prompt(prompt);
- (void) gets(line);
- makeargv();
- argc = margc;
- argv = margv;
- if (argc < 1) {
- p_help(helpstr);
- goto l1;
- }
- }
-
- len = strlen(argv[0]);
- if (!strncmp(argv[0], "text", len?len:1)) {
- type = ASCII;
- form = NONPRINT;
- strcpy(fil.filetype, "A N");
- }
- else if (!strncmp(argv[0], "ascii", len?len:1)) {
- set_form(--argc, ++argv,
- "(nonprint/telnet/carriage-control)",
- "File format (usually 'nonprint')");
- type = ASCII;
- sprintf(fil.filetype,"A %s",
- (form==NONPRINT)?"N":(form==TELNET)?"T":"C");
- }
- else if (!strncmp(argv[0], "ebcdic", len?len:1)) {
- set_form(--argc, ++argv,
- "(nonprint/telnet/carriage-control)",
- "File format (usually 'nonprint')");
- type = EBCDIC;
- sprintf(fil.filetype,"E %s",
- (form==NONPRINT)?"N":(form==TELNET)?"T":"C");
- }
- else if (!strncmp(argv[0], "local", len?len:1)) {
- set_number(--argc, ++argv,
- "(byte size)",
- "An integer byte size",
- &bytesiz);
- type = LOCAL;
- sprintf(fil.filetype,"L %d",bytesiz);
- }
- else if (!strncmp(argv[0], "image", len?len:1) ||
- !strncmp(argv[0], "binary", len?len:1)) {
- type = IMAGE;
- strcpy(fil.filetype,"I");
- }
- else {
- p_help(helpstr);
- goto l1;
- }
- } /* set_type */
-
- char *date_example =
- "Date and/or time to start transfer, e.g. '4 July 2001 4:01pm'";
-
- timecmd(argc, argv)
- int argc;
- char *argv[];
- {
- set_time(--argc, ++argv,
- "(start time -- <CR> means 'now')",
- date_example,
- 0);
- }
-
- interval(argc, argv)
- int argc;
- char *argv[];
- {
- set_number(--argc, ++argv,
- "(starting value for minutes between tries)",
- "An integer.",
- &req.interval);
- set_number(--argc, ++argv,
- "(maximum number of attempts)",
- "An integer.",
- &req.ntries);
-
- /* *** should interval and ntries be limited? */
- } /* timecmd */
-
- gethost(argc, argv)
- int argc;
- char *argv[];
- {
- boolean source = (argv[0][0] == 's');
- char temp[80];
- int len = strlen(def_hostname);
-
- sprintf(temp,"(host%s%s)",
- (len)?" -- <CR> means ":NULLSTR,
- (len)?def_hostname: NULLSTR);
-
- set_host(--argc, ++argv,
- temp,
- "Host name / dotted-decimal host number.",
- (source)?src.host:dst.host);
- }
-
- getuser(argc, argv)
- int argc;
- char *argv[];
- {
- boolean source = (argv[0][0] == 's');
-
- set_string(--argc, ++argv,
- "(login)",
- "User name / login.",
- (source)?src.user:dst.user);
- strcpy((source)?src.passwd:dst.passwd, getpass(" ( password) "));
- }
-
- explain(argc, argv)
- int argc;
- char *argv[];
- {
- printf("%s%s",introduction, explanation1);
- if (get_cr()) {
- printf(explanation2);
- if (get_cr()) {
- printf(terminology);
- if (get_cr())
- printf(background);
- }
- }
- }
-
- sExample(argc, argv)
- int argc;
- char *argv[];
- {
- char *seText1 =
- "\nSimple example using the 'prompt' command:\n\n\
- BFTP> prompt<CR>\n\
- text/binary: t<CR>\n\n\
- Source --\n\
- Host: venera.isi.edu<CR>\n\
- Login: anonymous<CR>\n\
- Password: guest<CR>\t[BFTP does not echo!]\n\
- Dir: pub/<CR>\n\
- File: sample-file.txt<CR>\n\n\
- Destination --\n\
- Host: hobgoblin.isi.edu<CR>\n\
- Login: deschon<CR>\n\
- Password: secret<CR>\t[BFTP does not echo!]\n\
- Dir:<CR>\t\t[leave blank for home directory]\n\
- File (blank if same as Source):<CR>\n\n\
- [BFTP displays the request]\n\n\
- ";
- char *seText2 =
- "\n\
- BFTP> verify<CR>\n\n\
- [BFTP verifies that the parameters are correct]\n\n\
- BFTP> submit<CR>\n\n\
- Checking parameters...\n\n\
- StartTime -- <CR> means 'now': 13:30<CR>\n\
- RequestKeyword (optional): <CR>\n\n\
- Request bftp637536643 submitted to run at Mar 15 13:30:43 1990 PST.\n\n\
- BFTP>\n\n\
- [end of example]\n\n\
- ";
-
- printf(seText1);
- if (get_cr())
- printf(seText2);
- }
-
- show()
- {
- char temp[40];
-
- printf("\n");
- print_req(stdout, &req, &src, &dst, &fil, TRUE);
-
- if (start) {
- format_time(start, temp);
- printf(" Start after %s. Verbose mode = %s\n",
- temp, (verbose)? "ON": "OFF");
- }
- else
- printf(" Start immediately. Verbose mode = %s\n",
- (verbose)? "ON": "OFF");
- }
-
- tmode(argc, argv)
- int argc;
- char *argv[];
- {
- set_tmode(--argc, ++argv,
- "(copy/move/delete)",
- "Transfer mode (usually 'copy')");
- }
-
- compose()
- {
- int len = strlen(def_hostname);
- u_long addr;
- char tmppass[MAXLEN];
- struct hostinfo *xxx;
- char temp[80];
-
- fil.reqtype = COPY;
-
- line[0] = '\0';
- makeargv();
- set_type(margc, margv,
- "text/binary:",
- "File type (text = 'a n'; binary = image;\n\
- \t ascii/ebcdic/image/local are also legal options)");
-
- for (xxx = &src; xxx ; xxx = (xxx == &src) ? &dst: NULL) {
- printf("\n %s --\n", (xxx == &src) ? "Source":"Destination");
-
- line[0] = '\0';
- makeargv();
- sprintf(temp,"Host name / dotted-decimal host number%s%s.",
- (len)?" / <CR> for ":NULLSTR,
- (len)?def_hostname: NULLSTR);
-
- set_host(margc, margv,
- " Host:",
- temp,
- xxx->host);
-
- line[0] = '\0';
- makeargv();
- set_string(margc, margv,
- " Login:",
- "User name / login.",
- xxx->user);
-
- strcpy(xxx->passwd, getpass(" Password: "));
-
- line[0] = '\0';
- makeargv();
- set_string(margc, margv,
- " Dir:",
- (xxx == &src)? "Directory where source file is located"
- : "Directory where destination file will be put",
- xxx->dir);
-
- line[0] = '\0';
- makeargv();
- set_string(margc, margv,
- (xxx == &src)? " File:"
- : " File (blank if same as Source):",
- "File name",
- xxx->file);
- }
-
- show();
- } /* compose */
-
- setapp(argc, argv)
- int argc;
- char *argv[];
- {
- int ret;
-
- ret = set_boolean(--argc, ++argv,
- "(true/false)",
- "Append file to existing destination file?");
-
- if (ret) fil.creation = APPE;
- else if (fil.creation != STOU) fil.creation = STOR;
- }
-
- setuniq(argc, argv)
- int argc;
- char *argv[];
- {
- int ret;
-
- ret = set_boolean(--argc, ++argv,
- "(true/false)",
- "Create unique file name using STOU command?");
-
- if (ret) fil.creation = STOU;
- else if (fil.creation != APPE) fil.creation = STOR;
- }
-
- setmult(argc, argv)
- int argc;
- char *argv[];
- {
- fil.multflag =
- set_boolean(--argc, ++argv,
- "(true/false)",
- "Enable wildcard matching?");
- if (fil.multflag) printf(
- "\nUse the VERIFY command to verify that your file list is correct!\n\n");
- }
-
- setverbose(argc, argv)
- int argc;
- char *argv[];
- {
- verbose =
- set_boolean(--argc, ++argv,
- "(true/false)",
- "Display FTP commands on verify and transfer commands?");
- }
-
- fstru(argc, argv)
- int argc;
- char *argv[];
- {
- set_stru(--argc, ++argv,
- "(file/record/page)",
- "Structure (usually 'file')");
- }
-
- ftype(argc, argv)
- int argc;
- char *argv[];
- {
- set_type(--argc, ++argv,
- "(text/binary or ascii/ebcdic/image/local)",
- "File type (text = 'a n'; binary = image;\n\
- \t ascii/ebcdic/image/local are also legal options)");
- } /* ftype */
-
- mode(argc, argv)
- int argc;
- char *argv[];
- {
- set_mode(--argc, ++argv,
- "(stream/block/compress)",
- "Mode (usually 'stream')");
- } /* mode */
-
- quit()
- {
- printf("Bye\n");
- exit(0);
- }
-
- dir(argc, argv)
- int argc;
- char *argv[];
- {
- boolean source = (argv[0][0] == 's');
-
- set_string(--argc, ++argv,
- "(directory)",
- (source)? "Directory where source file is located"
- : "Directory where destination file will be put",
- (source)? src.dir: dst.dir);
- }
-
- file(argc, argv)
- int argc;
- char *argv[];
- {
- boolean source = (argv[0][0] == 's');
-
- set_string(--argc, ++argv,
- "(file name)",
- (source)? "Source file name"
- : "Destination file name",
- (source)? src.file: dst.file);
- }
-
- passwd(argc, argv)
- int argc;
- char *argv[];
- {
- boolean source = (argv[0][0] == 's');
-
- strcpy((source)?src.passwd:dst.passwd, getpass(" Enter password: "));
- }
-
- acct(argc, argv)
- int argc;
- char *argv[];
- {
- boolean source = (argv[0][0] == 's');
-
- set_string(--argc, ++argv,
- "(acct)",
- "Account string for this login",
- (source)?src.acct:dst.acct);
- }
-
- port(argc, argv)
- int argc;
- char *argv[];
- {
- int port;
- boolean source = (argv[0][0] == 's');
-
- set_number(--argc, ++argv,
- "(port)",
- "Port number (usually 21)",
- &port);
- if (port > 0xffff)
- printf("?Illegal port number: %d\n", port);
- else
- if (source)
- src.port = port;
- else
- dst.port = port;
- }
-
- int
- finderrors()
- {
- u_long addr;
- int count = 0;
-
- printf("\nChecking parameters...\n\n");
-
- if (!resolve_name(src.host, &addr, 1)) {
- printf("Illegal source host number.\n");
- count++;
- }
- if (!strlen(src.user)) {
- printf("Source user name must be specified.\n");
- count++;
- }
- if (!strlen(src.file)) {
- printf("Source file name must be specified.\n");
- count++;
- }
-
- if (fil.reqtype != DFILE) {
- if (!resolve_name(dst.host, &addr, 1)) {
- printf("Illegal destination host number.\n");
- count++;
- }
- if (!strlen(dst.user)) {
- printf("Destination user name must be specified.\n");
- count++;
- }
-
- /* check the destination file name */
- if (fil.multflag) {
- if ((fil.creation != APPE) && (!empty_str(dst.file)))
- printf("Warning: destination file name will be ignored.\n");
- }
- else
- if ((fil.reqtype != DFILE) && empty_str(dst.file)) {
- printf("Destination file name must be specified.\n");
- count++;
- }
- }
-
- /* check for source directory on mult */
- if (fil.multflag &&
- (fil.reqtype != DFILE) && (!strlen(src.dir)) && !strlen(dst.file)) {
- printf(
- "Warning: For multiple file transfer, a source directory may be required.\n");
- line[0] = '\0';
- makeargv();
- if (!count) {
- set_string(margc, margv,
- "Directory:",
- "Directory where source file is located",
- src.dir);
- }
- }
-
- return(count);
- } /* finderrors */
-
- verify(argc, argv)
- int argc;
- char *argv[];
- {
- int save_mode,
- filelen = strlen(dst.file);
-
- if (!filelen)
- strcpy(dst.file, src.file);
- if (!finderrors()) {
- save_mode = fil.reqtype;
- fil.reqtype = (save_mode == DFILE)? VERIFY_SRC : VERIFY;
- submit_req(TRUE);
- fil.reqtype = save_mode;
- }
- if (!filelen)
- dst.file[0] = '\0';
- }
-
- transfernow(argc, argv)
- int argc;
- char *argv[];
- {
- int filelen = strlen(dst.file);
-
- if (!filelen)
- strcpy(dst.file, src.file);
- if (!finderrors())
- submit_req(TRUE);
- if (!filelen)
- dst.file[0] = '\0';
- }
-
- mailbox(argc, argv)
- int argc;
- char *argv[];
- {
- char temp[80];
- int len = strlen(def_mailbox);
-
- sprintf(temp,"(mailbox%s%s)",
- (len)?" -- <CR> means ":NULLSTR,
- (len)?def_mailbox: NULLSTR);
-
- set_mbox(--argc, ++argv,
- temp,
- "Mailbox to which results will be returned");
- }
-
- submit(argc, argv)
- int argc;
- char *argv[];
- {
- char timestr[40], prompt[80];
- char temp[80];
- int len = strlen(def_mailbox);
-
- int filelen = strlen(dst.file);
- if (!filelen)
- strcpy(dst.file, src.file);
- if (!finderrors()) {
- if (start)
- format_time(start, timestr);
- else
- strcpy(timestr, "now");
- sprintf(prompt, "StartTime -- <CR> means '%s':", timestr);
- set_time(--argc, ++argv,
- prompt,
- date_example,
- start);
-
- if (!strlen(req.mailbox)) {
- line[0] = '\0';
- makeargv();
- sprintf(temp,"ReturnMailbox%s%s:",
- (len)?" -- <CR> means ":NULLSTR,
- (len)?def_mailbox:NULLSTR);
- set_mbox(margc, margv,
- temp,
- "Mailbox to which results will be returned");
- }
-
- strcpy(req.rpasswd, getpass(" RequestKeyword (optional): "));
-
- submit_req(FALSE);
- }
- if (!filelen)
- dst.file[0] = '\0';
- }
-
- submit_req(realtime)
- int realtime;
- {
- FILE *xxx;
- char temp[MAXPATHLEN], path[MAXPATHLEN];
- u_long now;
-
- now = time(NULL);
- sprintf(path,"%s%d",REQPREFIX,now);
-
- sprintf(temp, "%s.req", path);
- if (realtime) {
- write_req(temp,&nullreq,&src,&dst,&fil,NULL);
- sprintf(temp, "%s %s%s.req\n", FXPATH, (verbose)?"-v ":NULLSTR, path);
- printf(temp);
- system(temp);
- }
- else {
- sprintf(req.mailfile,"%s.msg",path);
- sprintf(req.cmdfile,"%s.cmd",path);
- write_req(temp,&req,&src,&dst,&fil,NULL);
-
- sprintf(temp, "%s.cmd", path);
- xxx = fdopen(open(temp,(O_WRONLY|O_CREAT),0600),"w");
- fprintf(xxx, "%s -v %s.req\n", FXPATH, path);
- fclose(xxx);
-
- sprintf(temp, "%s.msg", path);
- xxx = fdopen(open(temp,(O_WRONLY|O_CREAT),0600),"w");
- queue_req(&req, (now > start) ? now : start, temp);
- print_req(xxx, &req, &src, &dst, &fil, FALSE);
- fprintf(xxx,"\n%s\n",temp);
- fclose(xxx);
- printf("\n%s\n\n",temp);
- }
- }
-
- /* Find and change/cancel a request */
-
- summarize(req)
- struct reqinfo *req;
- {
- char temp[150];
-
- if (strlen(req->mailfile)) {
- printf("History:\n\n");
- sprintf(temp,"egrep 'submitted|starting|completed' %s\n",req->mailfile);
- system(temp);
- printf("\n");
- }
- else
- printf("History: No mail file found!\n\n");
- }
-
- boolean
- ask(cp)
- char *cp;
- {
- char temp[40];
-
- sprintf(temp, "Do you wish to %s this request?", cp);
- line[0] = '\0';
- makeargv();
- return(set_boolean(margc, margv,
- temp,
- "Answer 'yes' or 'no'.")
- );
- }
-
- char *cancel_text = "\n Previous request cancelled.\n";
-
- find(argc, argv)
- int argc;
- char *argv[];
- {
- char password[MAXLEN], temp[MAXLEN], request[20], id [20];
- char filename[MAXPATHLEN], listfile[MAXPATHLEN], *filep;
- u_long now;
- boolean found;
- int tmp;
- struct hostinfo tmpsrc, tmpdst;
- struct fileinfo tmpfil;
- struct reqinfo tmpreq;
-
- line[0] = '\0';
- makeargv();
- set_string(margc, margv,
- "RequestID (optional):",
- "Request id, for example 'bftp123456789'.",
- request);
-
- if (strlen(request)) {
- sprintf(filename,"%s.req",request);
- if (! read_req(filename, &tmpreq, &tmpsrc, &tmpdst, &tmpfil, listfile)) {
- printf("\nRequest %s not found.\n",request);
- return;
- }
- }
-
- strcpy(password, getpass(" RequestKeyword: "));
-
- if (strlen(request))
- filep = filename;
- else
- filep = get_request_file(password);
-
- while (filep) {
- if ((read_req(filep, &tmpreq, &tmpsrc, &tmpdst, &tmpfil, listfile)) &&
- (strcmp(password, tmpreq.rpasswd) == 0)) {
- get_id(id, filep);
- printf("\nRequest: %s\n\n",id);
- print_req(stdout, &tmpreq, &tmpsrc, &tmpdst, &tmpfil, FALSE);
- summarize(&tmpreq);
-
- found = request_queued(filep);
- printf("\nYour request is %scurrently queued.\n",
- (found)?NULLSTR:"NOT ");
-
- if (ask("change")) {
- printf("\n Reading %s%s...\n",bftp_dir,filep);
- if (! read_req(filep,&req,&src,&dst,&fil,listfile))
- printf("\n Request file not found.\n");
- else {
- cancel_msg(filep, &tmpreq, tmpsrc.file, listfile);
- printf(cancel_text);
- unpack_filetype(fil.filetype,&type, &form, &bytesiz);
- show();
- printf("\nUse the 'submit' command to submit a new request.\n");
- close_listp();
- break;
- }
- }
- else
- if (ask("cancel")) {
- cancel_msg(filep, &tmpreq, tmpsrc.file, listfile);
- printf(cancel_text);
- }
- }
- if (strlen(request))
- break;
- else
- filep = get_request_file(password);
- }
- } /* find */
-
- /* Request file management routines */
-
- boolean
- reqname(argc, argv, nptr)
- int argc;
- char *argv[];
- char *nptr;
- {
- char temp[40], *cp;
-
- if (!strlen(def_user)) {
- printf(
- "\n\tSorry, you must be logged in for temporary request storage.\n\n");
- return(FALSE);
- }
- set_string(--argc, ++argv,
- "(request name)",
- NULL,
- temp);
-
- for (cp = temp; *cp && (*cp=='.' || *cp=='-' || isalnum(*cp)); cp++);
- if (*cp) {
- printf("\n?Alpha-numeric characters only please: %s\n",temp);
- return(FALSE);
- }
- else {
- sprintf(nptr, "%s.%s", SAVEPREFIX, temp);
- return(TRUE);
- }
- } /* reqname */
-
- delfile(argc, argv)
- int argc;
- char *argv[];
- {
- char rname[MAXLEN], temp[MAXLEN];
-
- if (reqname(argc, argv, rname)) {
- printf("\n Deleting...%s\n", rname);
- sprintf(temp, "rm %s", rname);
- system(temp);
- }
- }
-
- getfile(argc, argv)
- int argc;
- char *argv[];
- {
- char temp[MAXLEN], listfile[MAXLEN];
-
- if (reqname(argc, argv, temp)) {
- printf("\n Reading %s%s...\n",bftp_dir, temp);
- if (! read_req(temp,&req,&src,&dst,&fil,listfile))
- printf("\n Request file not found.\n");
- else {
- unpack_filetype(fil.filetype,&type, &form, &bytesiz);
- show();
- }
- }
- }
-
- savefile(argc, argv)
- int argc;
- char *argv[];
- {
- char temp[MAXLEN];
-
- if (reqname(argc, argv, temp)) {
- printf("\n File name = %s%s\n",bftp_dir, temp);
- write_req(temp,&req,&src,&dst,&fil,NULL);
- }
- }
-
- listsavef()
- {
- char **list, **temp;
- int i, maxlen = 0, linelen = 80;
-
- if (!strlen(def_user))
- printf(
- "\n\tSorry, you must be logged in for temporary request storage.\n\n");
- else {
- list = get_save_files();
- temp = list;
- while (*temp)
- if ((i = strlen(*temp++)) > maxlen) maxlen = i;
-
- maxlen += 4;
- while (*list) {
- if ((linelen+maxlen) > 80) {
- linelen = 2;
- printf("\n ");
- };
- printf("%-*s", maxlen, *list++);
- linelen += maxlen;
- }
- printf("\n\n");
- }
- } /* listsavef */
-
- init()
- {
- resolve_name(def_hostname, &local_addr, 1);
-
- strcpy(src.dir, NULLSTR);
- strcpy(src.file, NULLSTR);
- strcpy(src.host, NULLSTR);
- strcpy(src.user, NULLSTR);
- strcpy(src.passwd, NULLSTR);
- strcpy(src.acct, NULLSTR);
- src.port = DEFAULT_PORT;
- strcpy(dst.dir, NULLSTR);
- strcpy(dst.file, NULLSTR);
- strcpy(dst.host, NULLSTR);
- strcpy(dst.user, NULLSTR);
- strcpy(dst.passwd, NULLSTR);
- strcpy(dst.acct, NULLSTR);
- dst.port = DEFAULT_PORT;
-
- init_req(&req);
- strcpy(req.mailbox, NULLSTR);
- /* make the user enter it, at least the first time */
-
- fil.reqtype = COPY;
- fil.stru = 'F';
- type = ASCII;
- bytesiz = DEFAULT_BYTESZ;
- form = NONPRINT;
- strcpy(fil.filetype,"A N");
- fil.mode = 'S';
- start = 0;
- fil.creation = STOR;
- fil.multflag = FALSE;
- } /* init */
-
- /* Command table for BFTP */
-
- extern int help();
- int helpall();
-
- struct cmd cmdtab[] = {
- { "help",
- "List the commands ('help'), or print a description\n\
- \t (e.g. 'help prompt').",
- help },
- { "help-all",
- "Display a description of each command.",
- helpall },
- { "explain",
- "Display a detailed explanation of how to use this program.",
- explain },
- { "simple-example",
- "Display an example of how to enter and submit a request.",
- sExample },
-
- { "prompt",
- "Prompt for commonly-used parameters.",
- compose },
- { "show",
- "Display current parameter values.",
- show },
- { "init",
- "Return all parameters to their default values.",
- init },
-
- { "submit",
- "Submit the current request for background FTP.",
- submit },
- { "find",
- "Find and display a previous request (or cancel it).",
- find },
- { "transfer",
- "Perform the current request in the foreground.",
- transfernow },
- { "verify",
- "Make the connections now to check parameters.",
- verify },
- { "quit",
- "Exit the BFTP program.",
- quit },
-
- { "command",
- "Set the transfer mode.\n\
- \t copy: Source file is copied to the destination file name.\n\
- \t move: Source file is deleted after it has been copied.\n\
- \t delete: Source file is deleted.",
- tmode },
- { "mailbox",
- "Set the mailbox to which the results will be returned.",
- mailbox },
- { "verbose",
- "Set to true to show FTP commands on 'verify' & 'transfer'.",
- setverbose },
- { "time",
- "Date and/or time to start transfer.",
- timecmd },
- { "interval",
- "Starting retry interval in minutes, and number of tries.",
- interval },
-
- { "r-list",
- "List all bftp-save files.",
- listsavef },
- { "r-load",
- "Read a request file in as the current request.",
- getfile },
- { "r-store",
- "Save the current request in a file named 'bftp-save.name'.",
- savefile },
- { "r-delete",
- "Delete request file 'bftp-save.name'.",
- delfile },
-
- { "mode",
- "Set FTP mode to stream, block, or compress.",
- mode },
- { "stru",
- "Set FTP structure to file, record, or page.",
- fstru },
- { "type",
- "Set FTP type (ascii/ebcdic/image/local) & format/byte size.",
- ftype },
- { "multiple",
- "Set to true to transfer multiple files.",
- setmult },
- { "unique",
- "Set to true for unique file names (via the STOU command).",
- setuniq },
- { "append",
- "Set to true to append to destination file.",
- setapp },
-
- { "s-host",
- "Set the source host.",
- gethost },
- { "s-user",
- "Set the source login and password.",
- getuser },
- { "s-password",
- "Set the source password.",
- passwd },
- { "s-acct",
- "Set the account for the source login.",
- acct },
- { "s-dir",
- "Set the source directory.",
- dir },
- { "s-file",
- "Set the source file name.",
- file },
- { "s-port",
- "Set the port for the source FTP connection.",
- port },
-
- { "d-host",
- "Set the destination host.",
- gethost },
- { "d-user",
- "Set the destination login and password.",
- getuser },
- { "d-password",
- "Set the destination password.",
- passwd },
- { "d-acct",
- "Set the account for the destination login.",
- acct },
- { "d-dir",
- "Set the destination directory.",
- dir },
- { "d-file",
- "Set the destination file name.",
- file },
- { "d-port",
- "Set the port for the destination FTP connection.",
- port },
- { 0 },
- };
-
- int NCMDS = (sizeof (cmdtab) / sizeof (cmdtab[0])) - 1;
-
- helpall()
- {
- register char *p;
- register struct cmd *c;
-
- for (c = cmdtab; p = c->c_name; c++) {
- /* Print section divider */
- if (!strcmp(c->c_name, "s-host")) {
- if (!get_cr())
- break;
- printf("\nSet source parameter:\n\n");
- }
- else if (!strcmp(c->c_name, "d-host")) {
- /* if (!get_cr())
- break;
- */ printf("\nSet destination parameter:\n\n");
- }
- else if (!strcmp(c->c_name, "command")) {
- /* if (!get_cr())
- break;
- */ printf("\nSet internal BFTP parameter:\n\n");
- }
- else if (!strcmp(c->c_name, "mode")) {
- /* if (!get_cr())
- break;
- */ printf("\nSet FTP file parameter:\n\n");
- }
- else if (!strcmp(c->c_name, "r-list")) {
- if (!get_cr())
- break;
- printf("\nManage request files:\n\n");
- }
-
- /* Print help info */
- printf(" %-*s %s\n", HELPINDENT,
- c->c_name, c->c_help);
- }
- }
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- register char *cp;
- int ret;
-
- argc--, argv++;
- while (argc > 0 && **argv == '-') {
- for (cp = *argv + 1; *cp; cp++)
- switch (*cp) {
-
- default:
- fprintf(stderr, "bftp: %c: unknown option\n", *cp);
- exit(1);
- }
- argc--, argv++;
- }
-
- init_user();
- init();
-
- printf("\n%s %s\n\n%s\n",
- "Background File Transfer:", version,
- "For help type 'help' or '?'.\n");
- do_main();
- } /* main */
-