ports/78662: [PATCH] Metamail 2.7 incorrectly patched

Mats Peterson mats at sm5sxl.net
Thu Mar 10 07:00:16 UTC 2005


>Number:         78662
>Category:       ports
>Synopsis:       [PATCH] Metamail 2.7 incorrectly patched
>Confidential:   no
>Severity:       non-critical
>Priority:       high
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Mar 10 07:00:15 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Mats Peterson
>Release:        
>Organization:
>Environment:
>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.

	Since my original submission of the patch in 2002 (which went
	completely unprocessed), there has been another patch provided by
	a guy called Ulf Härnhammar.  His patch, however, doesn't correct
	the abovementioned issues.  I have included a patch that includes
	both my and Ulf's changes.

>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, and including
	Ulf Härnhammar's changes.

*** metamail.old/mailto.c	Wed Feb  9 21:30:26 1994
--- metamail/mailto.c	Thu Jul 29 14:32:28 2004
***************
*** 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;
*** metamail.old/metamail.c	Thu Feb 17 02:57:19 1994
--- metamail/metamail.c	Wed Mar  9 21:30:22 2005
***************
*** 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;
***************
*** 1202,1210 ****
      fprintf(outfp, "Content-type: %s", ContentType);
      for (j=0; j<CParamsUsed; ++j) {
          fprintf(outfp, " ; ");
!         fprintf(outfp, CParams[j]);
          fprintf(outfp, " = ");
!         fprintf(outfp, CParamValues[j]);
      }
      fprintf(outfp, "\n\n"); 
      TranslateInputToOutput(InputFP, outfp, EncodingCode, ContentType);
--- 1207,1215 ----
      fprintf(outfp, "Content-type: %s", ContentType);
      for (j=0; j<CParamsUsed; ++j) {
          fprintf(outfp, " ; ");
!         fprintf(outfp, "%s", CParams[j]);
          fprintf(outfp, " = ");
!         fprintf(outfp, "%s", CParamValues[j]);
      }
      fprintf(outfp, "\n\n"); 
      TranslateInputToOutput(InputFP, outfp, EncodingCode, ContentType);
***************
*** 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') {
***************
*** 2022,2028 ****
      if (lc2strcmp(charset, PrevCharset)) {
          char *s2, *charsetinuse;
  
!         strcpy(PrevCharset, charset);
          for (s2=PrevCharset; *s2; ++s2) {
              if (isupper((unsigned char) *s2)) *s2 = tolower((unsigned char) *s2);
          }
--- 2028,2035 ----
      if (lc2strcmp(charset, PrevCharset)) {
          char *s2, *charsetinuse;
  
!         strncpy(PrevCharset, charset, sizeof(PrevCharset));
!         PrevCharset[sizeof(PrevCharset) - 1] = '\0';
          for (s2=PrevCharset; *s2; ++s2) {
              if (isupper((unsigned char) *s2)) *s2 = tolower((unsigned char) *s2);
          }
***************
*** 2032,2038 ****
          }
      }
      if (ecode == ENCODING_NONE) {
!         printf(txt+1);
      } else {
          /* What follows is REALLY bogus, but all my encoding stuff is pipe-oriented right now... */
          MkTmpFileName(TmpFile);
--- 2039,2045 ----
          }
      }
      if (ecode == ENCODING_NONE) {
!         printf("%s", txt+1);
      } else {
          /* What follows is REALLY bogus, but all my encoding stuff is pipe-oriented right now... */
          MkTmpFileName(TmpFile);
>Release-Note:
>Audit-Trail:
>Unformatted:
 System: FreeBSD 4.6.2-RELEASE-p12
 



More information about the freebsd-ports-bugs mailing list