Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 16 Nov 2002 22:02:01 +0100 (CET)
From:      Mats Peterson <mats@snowbee.dyns.cx>
To:        FreeBSD-gnats-submit@FreeBSD.org
Cc:        mats@pc10.snowbee.foo
Subject:   ports/45343: Metamail 2.7 incorrectly patched [PATCH]
Message-ID:  <200211162102.gAGL21iN011679@pc10.snowbee.foo>

next in thread | raw e-mail | index | archive | help

>Number:         45343
>Category:       ports
>Synopsis:       Metamail 2.7 incorrectly patched [PATCH]
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-ports
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Nov 16 13:00:07 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Mats Peterson
>Release:        FreeBSD 4.6.2-RELEASE-p5 i386
>Organization:
>Environment:
System: FreeBSD 4.6.2-RELEASE-p5 i386

>Description:
	The file 'patch-af' for Metamail 2.7 replaces gets() with
	fgets() at several places in mailto.c and metamail.c.
	Unfortunately, the person who made the patch back in -95 seems
	to have overlooked the fact that fgets() retains the trailing
	newline character in the buffer, which leads to the test for
	string match in line 1809 of mailto.c (original source) never
	returning true.  Consequently, 'mailto' will report any manually
	entered content-type as not being listed in the local mailcap files.

>How-To-Repeat:
	When including non-text data with "~*" in the 'mailto' program,
	choose option 1 (Raw data from a file), and manually specify a
	content-type known to exist in the local mailcap files.

>Fix:
	Below is an updated "patch-af" with additional code to make fgets()
	work as expected in both mailto.c and metamail.c.
	Any old changes are kept intact.

diff -cr metamail.old/mailto.c metamail/mailto.c
*** metamail.old/mailto.c	Wed Feb  9 21:30:26 1994
--- metamail/mailto.c	Mon Nov 11 11:53:38 2002
***************
*** 570,575 ****
--- 570,576 ----
          if (isupper(*sdum)) *sdum = tolower(*sdum);
      }
      if (strcmp(CharacterSet, "us-ascii")
+ 	 && strcmp(CharacterSet, "koi8-r")
           && strncmp(CharacterSet, "iso-8859-", 9)) {
          fprintf(stderr, "mailto:  Unsupported character set: %s\n", CharacterSet);
          exit(-1);
***************
*** 1130,1135 ****
--- 1131,1137 ----
          if (part->isrich) {
              if (strcmp(CharacterSet, "us-ascii")
                   && (strncmp(CharacterSet, "iso-8859-", 9) 
+ 		     && strcmp(CharacterSet, "koi8-r")
                        || part->encoding_type_needed != ENC_NONE)) {
                  fprintf(fp, "Content-type: text/richtext; charset=\"%s\"\n", CharacterSet);
              } else {
***************
*** 1140,1145 ****
--- 1142,1148 ----
              WriteCtypeNicely(fp, part->content_type);
              if (strcmp(CharacterSet, "us-ascii")
                   && (strncmp(CharacterSet, "iso-8859-", 9) 
+ 		     && strcmp(CharacterSet, "koi8-r")
                        || part->encoding_type_needed != ENC_NONE)) {
                  fprintf(fp, "; charset=\"%s\"\n", CharacterSet);
              } else fputs("\n", fp);
***************
*** 1745,1750 ****
--- 1748,1754 ----
      }
      printf("\n\nEnter your choice as a number from 0 to %d: ", i);
      fflush(stdout);
+     *LineBuf = '\0';
      fgets(LineBuf, sizeof(LineBuf), stdin);
      ans = atoi(LineBuf);
      if (ans == 0 || ans == 1) {
***************
*** 1752,1759 ****
          FILE *fpi, *fpo;
  	printf("\nIf you want to include non-textual data from a file, enter the file name.\nTo include the output of a command, enter \"|\" followed by the command.\nIf you do not want to include anything, just press ENTER (RETURN).\n> ");
          fflush(stdout);
          fgets(CTLineBuf, sizeof(CTLineBuf), stdin);
!         sdum = CTLineBuf+strlen(CTLineBuf) -1;
          while (sdum >= CTLineBuf && isspace((unsigned char) *sdum)) {
              *sdum = '\0';
              --sdum;
--- 1756,1764 ----
          FILE *fpi, *fpo;
  	printf("\nIf you want to include non-textual data from a file, enter the file name.\nTo include the output of a command, enter \"|\" followed by the command.\nIf you do not want to include anything, just press ENTER (RETURN).\n> ");
          fflush(stdout);
+         *CTLineBuf = '\0';
          fgets(CTLineBuf, sizeof(CTLineBuf), stdin);
!         sdum = *CTLineBuf ? CTLineBuf+strlen(CTLineBuf) -1 : CTLineBuf;
          while (sdum >= CTLineBuf && isspace((unsigned char) *sdum)) {
              *sdum = '\0';
              --sdum;
***************
*** 1791,1797 ****
                  int ct;
                  printf("\nEnter the MIME Content-type value for the data from file %s\n    (type '?' for a list of locally-valid content-types): ", sdum);
                  fflush(stdout);
!                 gets(LineBuf);
                  if (index(LineBuf, '/')) {
                      char lc[100], *s, AnsBuf[100];
                      strcpy(lc, LineBuf);
--- 1796,1805 ----
                  int ct;
                  printf("\nEnter the MIME Content-type value for the data from file %s\n    (type '?' for a list of locally-valid content-types): ", sdum);
                  fflush(stdout);
!                 *LineBuf = '\0';
!                 fgets(LineBuf, sizeof(LineBuf), stdin);
!                 if (*LineBuf)
!                     LineBuf[strlen(LineBuf) - 1] = '\0';
                  if (index(LineBuf, '/')) {
                      char lc[100], *s, AnsBuf[100];
                      strcpy(lc, LineBuf);
***************
*** 1809,1815 ****
                      }
                      if (mc) break;
                      printf("The MIME content-type '%s' is not listed in your local mailcap files,\nand may not be a valid MIME type.  Do you want to use it anyway [no] ? ", LineBuf);
!                     s = gets(AnsBuf);
                      while (s && *s && isspace((unsigned char) *s)) ++s;
                      if (s && (*s == 'y' || *s == 'Y')) break;
                      continue;
--- 1817,1823 ----
                      }
                      if (mc) break;
                      printf("The MIME content-type '%s' is not listed in your local mailcap files,\nand may not be a valid MIME type.  Do you want to use it anyway [no] ? ", LineBuf);
!                     s = fgets(AnsBuf, sizeof(AnsBuf), stdin);
                      while (s && *s && isspace((unsigned char) *s)) ++s;
                      if (s && (*s == 'y' || *s == 'Y')) break;
                      continue;
***************
*** 2137,2142 ****
--- 2145,2151 ----
              printf("2: %s\n", CmdBuf);
              printf("\n\nEnter 1 or 2, or 0 to not edit it: ");
              fflush(stdout);
+             *LineBuf = '\0';
              fgets(LineBuf, sizeof(LineBuf), stdin);
              ans = atoi(LineBuf);
          } else ans = 2;
diff -cr metamail.old/metamail.c metamail/metamail.c
*** metamail.old/metamail.c	Thu Feb 17 02:57:19 1994
--- metamail/metamail.c	Mon Nov 11 11:56:21 2002
***************
*** 83,89 ****
  #define MAX_FILE_NAME_SIZE 256
  #define WRITE_BINARY	"w"
  #else /* AMIGA */
! extern char **environ, *gets();
  #define CATCOMMAND  "cat"
  #define CATTEMPLATE "cat %s"
  #define METAMAIL    "metamail"
--- 83,89 ----
  #define MAX_FILE_NAME_SIZE 256
  #define WRITE_BINARY	"w"
  #else /* AMIGA */
! extern char **environ;
  #define CATCOMMAND  "cat"
  #define CATTEMPLATE "cat %s"
  #define METAMAIL    "metamail"
***************
*** 540,545 ****
--- 540,546 ----
                      ans = 2;
                  } else {
                      printf("\nWhat do you want to do with the %s data?\n1 -- See it as text\n2 -- Write it to a file\n3 -- Just skip it\n\n", octetstream ? "raw" : ContentType);
+                     *Fname = '\0';
                      fgets(Fname, sizeof(Fname), stdin);
                      ans = atoi(Fname);
                  }
***************
*** 554,561 ****
                              needname = 0;
                              printf("Please enter the name of a file to which the data should be written\n(Default: %s) > ", suggestedname);
                              fflush(stdout);
                              fgets(Fname, sizeof(Fname), stdin);
!                             Fname[strlen(Fname) - 1] = '\0'; /* bogus newline */
  #if !defined(AMIGA) && !defined(MSDOS)
                              if (!Fname[0]) strcpy(Fname, suggestedname);
                              if (Fname[0] == '~' && Fname[1] == '/') {
--- 555,564 ----
                              needname = 0;
                              printf("Please enter the name of a file to which the data should be written\n(Default: %s) > ", suggestedname);
                              fflush(stdout);
+                             *Fname = '\0';
                              fgets(Fname, sizeof(Fname), stdin);
!                             if (*Fname)
!                                 Fname[strlen(Fname) - 1] = '\0'; /* bogus newline */
  #if !defined(AMIGA) && !defined(MSDOS)
                              if (!Fname[0]) strcpy(Fname, suggestedname);
                              if (Fname[0] == '~' && Fname[1] == '/') {
***************
*** 579,588 ****
                                  int overwriteans = -1;
                                  do {
                                      printf("File %s exists.  Do you want to overwrite it (y/n) ?\n", Fname);
!                                     s = gets(AnsBuf);
                                      if (!s) {
                                          overwriteans = 0;
                                      } else {
                                          while (s && *s && isspace((unsigned char) *s)) ++s;
                                          if (*s == 'y' || *s == 'Y' || !*s || *s == '\n') {
                                              overwriteans = 1;
--- 582,593 ----
                                  int overwriteans = -1;
                                  do {
                                      printf("File %s exists.  Do you want to overwrite it (y/n) ?\n", Fname);
!                                     *AnsBuf = '\0';
!                                     s = fgets(AnsBuf, sizeof(AnsBuf), stdin);
                                      if (!s) {
                                          overwriteans = 0;
                                      } else {
+                                         s[strlen(s) - 1] = '\0';
                                          while (s && *s && isspace((unsigned char) *s)) ++s;
                                          if (*s == 'y' || *s == 'Y' || !*s || *s == '\n') {
                                              overwriteans = 1;
***************
*** 1823,1830 ****
          } else {
              printf("This message contains '%s'-format data.\nDo you want to view it using the '%s' command (y/n) [y] ? ", ctype, ShortCommand(progname));
          }
!         s = gets(AnsBuf);
          if (!s) return(0); /* EOF */
  	while (s && *s && isspace((unsigned char) *s)) ++s;
  	if (*s == 'y' || *s == 'Y' || !*s || *s == '\n') return(1);
  	if (*s == 'n' || *s == 'N' || *s == 'q' || *s == 'Q') {
--- 1828,1836 ----
          } else {
              printf("This message contains '%s'-format data.\nDo you want to view it using the '%s' command (y/n) [y] ? ", ctype, ShortCommand(progname));
          }
!         s = fgets(AnsBuf, sizeof(AnsBuf), stdin);
          if (!s) return(0); /* EOF */
+         s[strlen(s) - 1] = '\0';
  	while (s && *s && isspace((unsigned char) *s)) ++s;
  	if (*s == 'y' || *s == 'Y' || !*s || *s == '\n') return(1);
  	if (*s == 'n' || *s == 'N' || *s == 'q' || *s == 'Q') {
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ports" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200211162102.gAGL21iN011679>