/* getfile ... this program uploads a file from a local system */ #define SOH 0x01 /* ascii start-of-header character */ #define STX 0x02 /* ascii start-of-text character */ #define ETX 0x03 /* ascii end-of-text character */ #define EOT 0x04 /* ascii end-of-transmission character */ #define ACK 0x06 /* ascii acknowledge character */ #define NAK 0x15 /* ascii non-acknowledge character */ #define CAN 0x18 /* ascii cancel character (ctrl-x) */ #define ESC 0x1b /* ascii escape character */ #define RETRIES 10 /* number of allowable transmission errors */ #define XFER_SIZE 64 /* max number of characters sent as a block */ #define CMODE 0644 /* creation mode for ascii files */ #define EMODE 0755 /* creation mode for executable files */ #define BINARY 0x01 /* flag byte bit settings */ #define QUERY 0x02 #define FATAL 0x04 #define ALLBIN 0x08 #define EXEC 0x10 /* mode flag is sent after the filename */ #define SECONDS 20 /* timeout interval */ #include #include struct sgttyb targ; char *tty, *ttyname(); char c, acknak, checksum, buffer[XFER_SIZE]; int high_count, low_count; int i, j, n_to_read, n_written, fd, tflags, success, unsuccess; int pmode; int timeout = 0; char *fname; char flags = 0; main (argc, argv) int argc; char **argv; { #ifdef __FreeBSD__ void time_out(); #else int time_out(); #endif signal(SIGALRM,time_out); /* set up alarm handling */ tty = ttyname(1); /* get name of the output file */ if (chmod(tty, 0600) == -1) /* write protect the terminal */ printf ("\ngetfile: unable to write protect the terminal\n"); gtty (0, &targ); /* get current terminal parameters */ tflags = targ.sg_flags; /* save flag word */ targ.sg_flags |= RAW ; /* set 1-char input, no parity output */ targ.sg_flags &= ~(ECHO | TANDEM); /* turn off echo, xon-xoff handling */ stty (0, &targ); while (--argc > 0) /* process all command line args */ { if ((*++argv)[0] == '-') /* test for command line option */ switch ((*argv)[1]) { case 'b': flags |= BINARY; /* set binary file type */ break; case 'q': flags |= QUERY; /* query file replacement */ break; case 'f': flags |= FATAL; /* suppress non-fatal messages */ break; case 'B': flags |= ALLBIN; /* all files are binary */ } else /* argument is a file name */ { c = 'y'; /* assume we are proceeding */ if (flags & QUERY) /* test for existing file */ if ((fd = open(*argv, 0)) != -1) /* file exists */ { printf ("replace %s (y/n)?", *argv); c = getchar() & 0177; /* could have parity so mask bit 7 */ printf ("%c\r\n", c); close (fd); } if (c == 'y') /* replace the file */ { printf ("%c%cS", SOH, ESC); /* SOH, escape, S - sequence for send */ scanf ("%c", &acknak); /* wait for local sys to get set up */ if (flags & ALLBIN) /* set binary if all files binary */ flags |= BINARY; putchar (flags); /* send the flag byte */ scanf ("%c", &acknak); /* wait for acknowledge */ checksum = 0; /* compute checksum to send */ fname = *argv; /* pointer to file name */ for (; **argv; (*argv)++) /* loop until end of name string */ if (**argv == '/') /* strip path name from string */ { fname = *argv; /* fname points to char after '/' */ fname++; checksum = 0; /* start checksum over */ } else checksum ^= **argv; /* checksum is xor of filename chars */ acknak = NAK; /* no acknowledge so far */ /* send the filename first and get an ACK. Try RETRIES times */ for (i=0; i