egray@fthood.UUCP (07/18/88)
This is an *UN*offical patch to the version of Steve Grandi's xmodem version 3.6 that was posted here a few days ago. I had made plenty of changes to the 3.5 version, and a missed one when I did the 3.6 work-over... I missed the modification that fixed the end of the file that are recieved by striping the control Z's. Emmet P. Gray US Army, HQ III Corps & Fort Hood ...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV Directorate of Engineering & Housing Environmental Management Office Fort Hood, TX 76544-5057 ---------------------------------------------------------------------------- *** old/Makefile Sun Jul 17 21:00:47 1988 --- Makefile Sat Jul 16 23:05:19 1988 *************** *** 2,8 LDFLAGS = -s #CFLAGS = -O # see the Readme.local file for what these do. ! CFLAGS = -O -DSYSV -DNOCLOBBER -DLOCAL xmodem: $(OBJECTS) # for users of AT&T Unix PC 7300/3b1 --- 2,8 ----- LDFLAGS = -s #CFLAGS = -O # see the Readme.local file for what these do. ! CFLAGS = -O -DSYSV -DNOCLOBBER -DFIX_END -DLOCAL xmodem: $(OBJECTS) # for users of AT&T Unix PC 7300/3b1 *** old/Readme.local Sun Jul 17 21:00:47 1988 --- Readme.local Sat Jul 16 23:12:23 1988 *************** *** 10,16 overwriting an existing file. If batch, create unique names. ! LOCAL Change a bunch of default settings: 1) binary xfers assumed, 'b' option is optional. 2) CRC is assumed, 'c' option is now for checksum --- 10,17 ----- overwriting an existing file. If batch, create unique names. ! FIX_END Fix the end of recieved files by removing the ! trailing control Z's. LOCAL Change a bunch of default settings: 1) binary xfers assumed, 'b' option is optional. *************** *** 12,17 LOCAL Change a bunch of default settings: 1) binary xfers assumed, 'b' option is optional. 2) CRC is assumed, 'c' option is now for checksum 3) loging defaults to off, 'l' turns it on. --- 13,19 ----- FIX_END Fix the end of recieved files by removing the trailing control Z's. + LOCAL Change a bunch of default settings: 1) binary xfers assumed, 'b' option is optional. 2) CRC is assumed, 'c' option is now for checksum 3) loging defaults to off, 'l' turns it on. *************** *** 16,23 2) CRC is assumed, 'c' option is now for checksum 3) loging defaults to off, 'l' turns it on. ! The manual page with a lower case 'l' is edited to reflect the NOCLOBBER ! and LOCAL options. For users of the AT&T Unix PC 7300/3b1, there is a line in the Makefile that will allow the program to be compiled with shared libraries. --- 18,25 ----- 2) CRC is assumed, 'c' option is now for checksum 3) loging defaults to off, 'l' turns it on. ! The manual page 'xmodem.local' is edited to reflect the NOCLOBBER, ! FIX_END, and LOCAL options. For users of the AT&T Unix PC 7300/3b1, there is a line in the Makefile that will allow the program to be compiled with shared libraries. *** old/getput.c Sun Jul 17 21:00:52 1988 --- getput.c Thu Jul 14 16:40:19 1988 *************** *** 389,395 if (ioctl(0,TCGETA,&ttystemp) < 0) /* get tty structure */ error("Can't get TTY parameters", FALSE); ! if ((ttystemp.c_cflag & 017)<=14) { ttyspeed = speedtbl[ttystemp.c_cflag & 017]; logitarg ("Line speed = %d bits per second\n", ttyspeed); --- 389,395 ----- if (ioctl(0,TCGETA,&ttystemp) < 0) /* get tty structure */ error("Can't get TTY parameters", FALSE); ! if ((ttystemp.c_cflag & 017) <= 14) { ttyspeed = speedtbl[ttystemp.c_cflag & 017]; logitarg ("Line speed = %d bits per second\n", ttyspeed); *** old/getput.sysv.c Sun Jul 17 21:00:54 1988 --- getput.sysv.c Thu Jul 14 16:41:01 1988 *************** *** 389,395 if (ioctl(0,TCGETA,&ttystemp) < 0) /* get tty structure */ error("Can't get TTY parameters", FALSE); ! if ((ttystemp.c_cflag & 017)<=14) { ttyspeed = speedtbl[ttystemp.c_cflag & 017]; logitarg ("Line speed = %d bits per second\n", ttyspeed); --- 389,395 ----- if (ioctl(0,TCGETA,&ttystemp) < 0) /* get tty structure */ error("Can't get TTY parameters", FALSE); ! if ((ttystemp.c_cflag & 017) <= 14) { ttyspeed = speedtbl[ttystemp.c_cflag & 017]; logitarg ("Line speed = %d bits per second\n", ttyspeed); *** old/receive.c Sun Jul 17 21:00:28 1988 --- receive.c Sat Jul 16 23:25:04 1988 *************** *** 459,464 if (openflag) /* close the file */ close(fd); sendbyte(ACK); /* ACK the EOT */ logit("Receive Complete\n"); prtime (recvsectcnt, time((time_t *) 0) - start); --- 459,468 ----- if (openflag) /* close the file */ close(fd); sendbyte(ACK); /* ACK the EOT */ + #ifdef FIX_END + if (CHECKLENGTH == FALSE) + fix_end(name); + #endif /* FIX_END */ logit("Receive Complete\n"); prtime (recvsectcnt, time((time_t *) 0) - start); *************** *** 491,493 return(FALSE); } --- 495,575 ----- return(FALSE); } + + #ifdef FIX_END + fix_end(name) + char *name; + { + FILE *fp; + int code; + long true_end; + + if (!(fp = fopen(name, "r"))) { + fprintf(stderr, "fix_end: Can't open '%s' for read\n", name); + return(1); + } + + fseek(fp, 0L, 2); + true_end = ftell(fp); + fseek(fp, -1L, 1); + while (getc(fp) == 0x1a) { /* find true EOF */ + true_end--; + fseek(fp, -2L, 1); + } + fclose(fp); + code = fix_length(name, true_end); + return(code); + } + + /* + * Shorten a file to a predetermined length. Used to remove the ^Z + * padding from the end of files. (Heaven help us, if one day a binary + * file actually has ^Z's as part of the end of the file). + */ + + int + fix_length(file, len) + char *file; + long len; + { + FILE *fp, *tempfp; + register int num; + char *tempfile, *mktemp(), buf[BUFSIZ]; + + if (!(fp = fopen(file, "r"))) + return(1); + + /* + * The temporary file should be in the same directory as the + * file being received because otherwise we'd have no way of + * guaranteeing they would be in the same file system. (Hard + * links across different file systems aren't allowed). + */ + tempfile = mktemp("trunXXXXXX"); + if (!(tempfp = fopen(tempfile, "w"))) { + fclose(fp); + return(1); + } + + while(len) { + num = (len > BUFSIZ) ? BUFSIZ : len; + fread(buf, sizeof(char), num, fp); + fwrite(buf, sizeof(char), num, tempfp); + len -= (unsigned int) num; + } + + fclose(fp); + fclose(tempfp); + + if (unlink(file) < 0) + return(1); + + if (link(tempfile, file) < 0) + return(1); + + if (unlink(tempfile) < 0) + return(1); + + return(0); + } + #endif /* FIX_END */ *** old/xmodem.c Sun Jul 17 21:00:30 1988 --- xmodem.c Sat Jul 16 14:44:13 1988 *************** *** 44,49 char ans[10]; #endif /* NOCLOBBER */ #ifdef LOCAL XMITTYPE = 'b'; /* assume binary transfer */ #else /* LOCAL */ XMITTYPE = 't'; /* assume text transfer */ --- 44,50 ----- char ans[10]; #endif /* NOCLOBBER */ #ifdef LOCAL + int fd; XMITTYPE = 'b'; /* assume binary transfer */ #else /* LOCAL */ XMITTYPE = 't'; /* assume text transfer */ *************** *** 219,225 if(open(argv[2], 0) != -1) /* check for overwriting */ #ifdef NOCLOBBER while(1) { ! printf("File exists - overwrite (y/n)? "); gets(ans); if (ans[0] == 'n' || ans[0] == 'N') exit(0); --- 220,226 ----- if(open(argv[2], 0) != -1) /* check for overwriting */ #ifdef NOCLOBBER while(1) { ! printf("File '%s' exists - overwrite (y/n)? ", argv[2]); gets(ans); if (ans[0] == 'n' || ans[0] == 'N') exit(0); *************** *** 233,238 fprintf(stderr, "Warning -- Target File Exists and is Being Overwritten\n"); #endif /* NOCLOBBER */ } fprintf(stderr, "Ready to RECEIVE File %s", argv[2]); fprintf(stderr, " in %s mode\n", prtype(XMITTYPE)); fprintf(stderr, "Send several Control-X characters to cancel\n"); --- 234,248 ----- fprintf(stderr, "Warning -- Target File Exists and is Being Overwritten\n"); #endif /* NOCLOBBER */ } + #ifdef LOCAL + /* check write permission */ + if ((fd = open(argv[2], O_WRONLY|O_CREAT, 0666)) < 0) { + fprintf(stderr, "No write permission on file '%s'\n", argv[2]); + exit(1); + } + close(fd); + fprintf(stderr, "Ready to RECEIVE File '%s'", argv[2]); + #else /* LOCAL */ fprintf(stderr, "Ready to RECEIVE File %s", argv[2]); #endif /* LOCAL */ fprintf(stderr, " in %s mode\n", prtype(XMITTYPE)); *************** *** 234,239 #endif /* NOCLOBBER */ } fprintf(stderr, "Ready to RECEIVE File %s", argv[2]); fprintf(stderr, " in %s mode\n", prtype(XMITTYPE)); fprintf(stderr, "Send several Control-X characters to cancel\n"); logitarg("Receiving in %s mode\n", prtype(XMITTYPE)); --- 244,250 ----- fprintf(stderr, "Ready to RECEIVE File '%s'", argv[2]); #else /* LOCAL */ fprintf(stderr, "Ready to RECEIVE File %s", argv[2]); + #endif /* LOCAL */ fprintf(stderr, " in %s mode\n", prtype(XMITTYPE)); fprintf(stderr, "Send several Control-X characters to cancel\n"); logitarg("Receiving in %s mode\n", prtype(XMITTYPE)); *************** *** 294,299 error("Can't find requested file", FALSE); expsect = (filestatbuf.st_size/128)+1; fprintf(stderr, "File %s Ready to SEND", argv[2]); fprintf(stderr, " in %s mode\n", prtype(XMITTYPE)); fprintf(stderr, "Estimated File Size %ldK, %ld Sectors, %ld Bytes\n", --- 305,313 ----- error("Can't find requested file", FALSE); expsect = (filestatbuf.st_size/128)+1; + #ifdef LOCAL + fprintf(stderr, "File '%s' Ready to SEND", argv[2]); + #else /* LOCAL */ fprintf(stderr, "File %s Ready to SEND", argv[2]); #endif /* LOCAL */ fprintf(stderr, " in %s mode\n", prtype(XMITTYPE)); *************** *** 295,300 expsect = (filestatbuf.st_size/128)+1; fprintf(stderr, "File %s Ready to SEND", argv[2]); fprintf(stderr, " in %s mode\n", prtype(XMITTYPE)); fprintf(stderr, "Estimated File Size %ldK, %ld Sectors, %ld Bytes\n", (filestatbuf.st_size/1024)+1, expsect, --- 309,315 ----- fprintf(stderr, "File '%s' Ready to SEND", argv[2]); #else /* LOCAL */ fprintf(stderr, "File %s Ready to SEND", argv[2]); + #endif /* LOCAL */ fprintf(stderr, " in %s mode\n", prtype(XMITTYPE)); fprintf(stderr, "Estimated File Size %ldK, %ld Sectors, %ld Bytes\n", (filestatbuf.st_size/1024)+1, expsect, *** old/xmodem.h Sun Jul 17 21:00:32 1988 --- xmodem.h Sat Jul 16 22:38:09 1988 *************** *** 2,7 #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #ifdef SYSV #include <time.h> #include <termio.h> --- 2,8 ----- #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> + #include <fcntl.h> #ifdef SYSV #include <time.h> #include <termio.h> *** old/xmodem.l Sun Jul 17 21:00:39 1988 --- xmodem.l Sun Jul 17 21:28:58 1988 *************** *** 32,38 .I xmodem will prompt the user before overwriting an existing file of the same name. Batch protocols avoid file name collisions by prepending the letter 'X' to ! the file name. .TP .B rt Receive Text - files are converted from the CP/M and MS-DOS --- 32,38 ----- .I xmodem will prompt the user before overwriting an existing file of the same name. Batch protocols avoid file name collisions by prepending the letter 'X' to ! the offending file name. .TP .B rt Receive Text - files are converted from the CP/M and MS-DOS *************** *** 127,133 will be stored under their transmitted names (except that any "/" characters in the file name will be converted into ":" characters, all upper-case characters will be translated into lower case and trailing dots will be ! expunged). .PP When a batch receive is requested, .I xmodem --- 127,134 ----- will be stored under their transmitted names (except that any "/" characters in the file name will be converted into ":" characters, all upper-case characters will be translated into lower case and trailing dots will be ! expunged). Be aware the file names may be altered by the addition of ! a leading 'X' to avoid file name collisions. .PP When a batch receive is requested, .I xmodem *************** *** 167,172 incoming file are correctly handled). File sizes are included in the YMODEM header when sending both binary and text files. Thus files transferred via YMODEM should preserve their exact length. File modification times are set for received files if present in the YMODEM header; they are included in the headers for transmitted files. .PP --- 168,175 ----- incoming file are correctly handled). File sizes are included in the YMODEM header when sending both binary and text files. Thus files transferred via YMODEM should preserve their exact length. + Files received using other protocols are striped of the trailing + control Z's (if any) in order to preserve their length. File modification times are set for received files if present in the YMODEM header; they are included in the headers for transmitted files. .PP