Subject: makesimtape long/int bug, mail can corrupt inbox (#408) Index: sys/pdpstand/makesimtape.c,bin/mail.c 2.11BSD Description: On a PDP-11 "sizeof long != sizeof int". The makesimtape program had 'int' where there should have been a 'long'. /bin/mail can leave the inbox corrupted if an error (disk full for example) occurs while appending a mail item to the inbox. Repeat-By: Run makesimtape on a PDP-11 to create a tape image for use with Bob Supnik's simulator. The end of file indicators will be corrupt and tape I/O will not function correctly. Thanks go to Robin Birch for debugging and providing the fix. In the words of the person who found the bug and supplied the initial fix (thanks go to Megan Gentry): The problem which was occuring was that if a message was sent to a user, and there was insufficient space to receive the entire message, it was possible for a partial message to be delivered. This in itself isn't bad, except for the fact that a subsequent message will appear to disappear since the partial message won't have a complete final line... so the 'From xxx...' message for a new message doesn't go on a line of it's own. Fix: Cut where indicated and save to a file (/tmp/408). Then: patch -p0 < /tmp/408 cd /usr/src/bin make mail install -s -m 4751 -o root mail /bin/mail cd /sys/pdpstand make makesimtape That's all there is this time. A small patch to start 1999 off. As always this and previous updates to 2.11BSD are available via anonymous FTP to either FTP.IIPO.GTEGSC.COM or MOE.2BSD.COM in the directory /pub/2.11BSD. -------------------------------cut here--------------------------- *** /usr/src/sys/pdpstand/makesimtape.c.old Mon Aug 11 20:21:11 1997 --- /usr/src/sys/pdpstand/makesimtape.c Thu Dec 31 20:16:35 1998 *************** *** 1,5 **** /* ! * @(#)makesimtape.c 2.0 (2.11BSD) 1997/8/7 * Hacked 'maketape.c' to write a file in a format suitable for * use with Bob Supnik's PDP-11 simulator (V2.3) emulated tape * driver. --- 1,5 ---- /* ! * @(#)makesimtape.c 2.1 (2.11BSD) 1998/12/31 * Hacked 'maketape.c' to write a file in a format suitable for * use with Bob Supnik's PDP-11 simulator (V2.3) emulated tape * driver. *************** *** 32,38 **** int argc; char *argv[]; { ! int i, j = 0, k = 0, zero = 0; register char *outfile = NULL, *infile = NULL; FILE *mf; struct stat st; --- 32,39 ---- int argc; char *argv[]; { ! int i, j = 0, k = 0; ! long zero = 0; register char *outfile = NULL, *infile = NULL; FILE *mf; struct stat st; *** /usr/src/bin/mail.c.old Thu Oct 2 20:20:01 1997 --- /usr/src/bin/mail.c Thu Dec 31 12:45:58 1998 *************** *** 1,5 **** #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)mail.c 4.33.4 (2.11BSD GTE) 1997/10/2"; #endif #include --- 1,5 ---- #if !defined(lint) && defined(DOSCCS) ! static char sccsid[] = "@(#)mail.c 4.33.5 (2.11BSD) 1998/12/31"; #endif #include *************** *** 595,603 **** char *name, *fromaddr; { char file[256]; ! int mask, fd; struct passwd *pw; char buf[128]; if (*name=='!') name++; --- 595,604 ---- char *name, *fromaddr; { char file[256]; ! int fd; struct passwd *pw; char buf[128]; + off_t oldsize; if (*name=='!') name++; *************** *** 610,620 **** cat(file, maildir, name); if (!safefile(file)) return(0); ! fd = open(file, O_WRONLY | O_CREAT, MAILMODE); ! if (fd >= 0) { ! flock(fd, LOCK_EX); malf = fdopen(fd, "a"); - } if (fd < 0 || malf == NULL) { close(fd); printf("mail: %s: cannot append\n", file); --- 611,619 ---- cat(file, maildir, name); if (!safefile(file)) return(0); ! fd = open(file, O_WRONLY | O_CREAT | O_EXLOCK, MAILMODE); ! if (fd >= 0) malf = fdopen(fd, "a"); if (fd < 0 || malf == NULL) { close(fd); printf("mail: %s: cannot append\n", file); *************** *** 621,628 **** return(0); } fchown(fd, pw->pw_uid, pw->pw_gid); ! (void)sprintf(buf, "%s@%ld\n", name, ftell(malf)); ! copylet(n, malf, ORDINARY); fclose(malf); notifybiff(buf); return(1); --- 620,646 ---- return(0); } fchown(fd, pw->pw_uid, pw->pw_gid); ! oldsize = ftell(malf); ! (void)sprintf(buf, "%s@%ld\n", name, oldsize); ! ! copylet(n, malf, ORDINARY); /* Try to deliver the message */ ! ! /* If there is any error during the delivery of the message, ! * the mail file may be corrupted (incomplete last line) and ! * any subsequent mail will be apparently lost, since the ! * before the 'From ' won't be there. So, restore the ! * file to the pre-delivery size and report an error. ! * ! * fflush does "_flag |= _IOERR" so we don't need to check both the ! # return from fflush and the ferror status. ! */ ! (void)fflush(malf); ! if (ferror(malf)) { ! printf("mail: %s: cannot append\n", file); ! ftruncate(fd, oldsize); ! fclose(malf); ! return(0); ! } fclose(malf); notifybiff(buf); return(1); *** /VERSION.old Tue Sep 15 21:04:06 1998 --- /VERSION Thu Dec 31 20:27:01 1998 *************** *** 1,5 **** ! Current Patch Level: 407 ! Date: September 15, 1998 2.11 BSD ============ --- 1,5 ---- ! Current Patch Level: 408 ! Date: December 31, 1998 2.11 BSD ============