Changeset 411:a60586461eb8

Show
Ignore:
Timestamp:
1998-08-25 15:19:47 (10 years ago)
Author:
Thomas Roessler <roessler@…>
Branch:
mutt-0-94
Message:

[patch-0.94.4i.tlr.nametemplate.1] Fix nametemplate
support: We should not move the user's files around just
to make them match mailcap's idea of their file name.
This patch uses symbolic links instead.

Files:
3 modified

Legend:

Unmodified
Added
Removed
  • TODO

    r407 r411  
    110110 
    111111 
     112- Re-visit nametemplate support.  Currently, we use 
     113  symbolic links in our temporary directory for this. 
     114 
     115 
    112116- BODY struct should probably have a pointer to its 
    113117  corresponding HEADER struct.  this is needed for 
     
    116120  STATE struct so that all of the MIME handlers can look 
    117121  up the corresponding HEADERs if need be? 
    118  
    119 - rfc1524_expand_filename() doesn't work as expected, as 
    120   it doesn't honor $tmpdir under some conditions if 
    121   matching nametemplates exist. 
    122122 
    123123- option to not include attachments in replies 
  • attach.c

    r364 r411  
    4646  char type[STRING]; 
    4747  char command[STRING]; 
     48  char newfile[_POSIX_PATH_MAX] = ""; 
    4849  rfc1524_entry *entry = rfc1524_new_entry (); 
    49  
     50  short unlink_newfile = 0; 
     51  int rc = 0; 
     52   
    5053  snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype); 
    5154  if (rfc1524_mailcap_lookup (a, type, entry, M_COMPOSE)) 
     
    5356    if (entry->composecommand || entry->composetypecommand) 
    5457    { 
    55       char newfile[_POSIX_PATH_MAX] = ""; 
    5658 
    5759      if (entry->composetypecommand) 
     
    6466        dprint(1, (debugfile, "oldfile: %s\t newfile: %s\n", 
    6567                                  a->filename, newfile)); 
    66         if (!mutt_rename_file (a->filename, newfile)) 
     68        if (symlink (a->filename, newfile) == -1) 
    6769        { 
    6870          if (!mutt_yesorno ("Can't match nametemplate, continue?", 1)) 
    69             return 0; 
     71            goto bailout; 
    7072        } 
    71         else 
    72         { 
    73           safe_free ((void **) &a->filename); 
    74           a->filename = safe_strdup (newfile); 
    75         } 
    76       } 
    77  
    78       if (rfc1524_expand_command (a, a->filename, type, 
     73        unlink_newfile = 1; 
     74      } 
     75      else 
     76        strfcpy(newfile, a->filename, sizeof(newfile)); 
     77       
     78      if (rfc1524_expand_command (a, newfile, type, 
    7979                                      command, sizeof (command))) 
    8080      { 
     
    9595          { 
    9696            mutt_perror ("Failure to open file to parse headers."); 
    97             return 0; 
     97            goto bailout; 
    9898          } 
    9999 
     
    126126            { 
    127127              mutt_perror ("Failure to open file to strip headers."); 
    128               return 0; 
     128              goto bailout; 
    129129            } 
    130130            mutt_copy_stream (fp, tfp); 
     
    147147  } 
    148148 
     149  rc = 1; 
     150   
     151  bailout: 
     152   
     153  if(unlink_newfile) 
     154    unlink(newfile); 
     155 
    149156  rfc1524_free_entry (&entry); 
    150   return 1; 
     157  return rc; 
    151158} 
    152159 
     
    164171  char type[STRING]; 
    165172  char command[STRING]; 
     173  char newfile[_POSIX_PATH_MAX] = ""; 
    166174  rfc1524_entry *entry = rfc1524_new_entry (); 
    167  
     175  short unlink_newfile = 0; 
     176  int rc = 0; 
     177   
    168178  snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype); 
    169179  if (rfc1524_mailcap_lookup (a, type, entry, M_EDIT)) 
     
    171181    if (entry->editcommand) 
    172182    { 
    173       char newfile[_POSIX_PATH_MAX] = ""; 
    174183 
    175184      strfcpy (command, entry->editcommand, sizeof (command)); 
     
    179188        dprint(1, (debugfile, "oldfile: %s\t newfile: %s\n", 
    180189                                  a->filename, newfile)); 
    181         if (mutt_rename_file (a->filename, newfile)) 
     190        if (symlink (a->filename, newfile) == -1) 
    182191        { 
    183192          if (!mutt_yesorno ("Can't match nametemplate, continue?", 1)) 
    184             return 0; 
     193            goto bailout; 
    185194        } 
    186         else 
    187         { 
    188           safe_free ((void **) &a->filename); 
    189           a->filename = safe_strdup (newfile); 
    190         } 
    191       } 
    192  
    193       if (rfc1524_expand_command (a, a->filename, type, 
     195        unlink_newfile = 1; 
     196      } 
     197      else 
     198        strfcpy(newfile, a->filename, sizeof(newfile)); 
     199 
     200      if (rfc1524_expand_command (a, newfile, type, 
    194201                                      command, sizeof (command))) 
    195202      { 
     
    208215    /* On text, default to editor */ 
    209216    mutt_edit_file ((!Editor || strcmp ("builtin", Editor) == 0) ?  
    210                     NONULL(Visual) : NONULL(Editor), a->filename); 
     217                    NONULL(Visual) : NONULL(Editor), newfile); 
    211218  } 
    212219  else 
     
    217224  } 
    218225 
     226  rc = 1; 
     227   
     228  bailout: 
     229   
     230  if(unlink_newfile) 
     231    unlink(newfile); 
     232   
    219233  rfc1524_free_entry (&entry); 
    220   return 1; 
     234  return rc; 
    221235} 
    222236 
     
    254268  rfc1524_entry *entry = NULL; 
    255269  int rc = -1; 
    256  
     270  int unlink_tempfile = 0; 
     271   
    257272  is_message = mutt_is_message_type(a->type, a->subtype); 
    258273#ifdef _PGPPATH 
     
    305320      { 
    306321        /* send case: the file is already there */ 
    307         if (mutt_rename_file (a->filename, tempfile)) 
     322        if (symlink (a->filename, tempfile) == -1) 
    308323        { 
    309324          if (mutt_yesorno ("Can't match nametemplate, continue?", 1) == M_YES) 
     
    313328        } 
    314329        else 
    315         { 
    316           safe_free ((void **) &a->filename); 
    317           a->filename = safe_strdup (tempfile); 
    318         } 
     330          unlink_tempfile = 1; 
    319331      } 
    320332    } 
     
    469481  if (fp && tempfile[0]) 
    470482    mutt_unlink (tempfile); 
     483  else if (unlink_tempfile) 
     484    unlink(tempfile); 
     485 
    471486  if (pagerfile[0]) 
    472487    mutt_unlink (pagerfile); 
     
    735750  pid_t thepid; 
    736751  FILE *ifp, *fpout; 
    737  
     752  short unlink_newfile = 0; 
     753   
    738754  snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype); 
    739755 
     
    751767      if (!fp) 
    752768      { 
    753         /* only attempt file move in send mode */ 
    754  
    755         if (mutt_rename_file (a->filename, newfile)) 
     769        if (symlink(a->filename, newfile) == -1) 
    756770        { 
    757771          if (mutt_yesorno ("Can't match nametemplate, continue?", 1) != M_YES) 
     
    763777        } 
    764778        else 
    765         { 
    766           safe_free ((void **)&a->filename); 
    767           a->filename = safe_strdup (newfile); 
    768         } 
     779          unlink_newfile = 1; 
    769780      } 
    770781    } 
     
    804815    if (fp) 
    805816      mutt_unlink (newfile); 
     817    else if (unlink_newfile) 
     818      unlink(newfile); 
    806819 
    807820    rfc1524_free_entry (&entry); 
     
    811824  if (!strcasecmp ("text/plain", a->subtype) || 
    812825      !strcasecmp ("application/postscript", a->subtype)) 
     826  { 
    813827    return (mutt_pipe_attachment (fp, a, NONULL(PrintCmd), NULL)); 
     828  } 
    814829  else if (mutt_can_decode (a)) 
    815830  { 
  • rfc1524.c

    r348 r411  
    5656  char buf[LONG_STRING]; 
    5757 
    58   while (command[x] && x<clen && y<sizeof(buf)) { 
     58  while (command[x] && x<clen && y<sizeof(buf))  
     59  { 
    5960    if (command[x] == '\\') { 
    6061      x++; 
    6162      buf[y++] = command[x++]; 
    6263    } 
    63     else if (command[x] == '%') { 
     64    else if (command[x] == '%')  
     65    { 
    6466      x++; 
    65       if (command[x] == '{') { 
     67      if (command[x] == '{')  
     68      { 
    6669        char param[STRING]; 
    6770        int z = 0; 
     
    422425  char tmp[_POSIX_PATH_MAX]; 
    423426  char *period; 
    424  
     427  size_t sl; 
     428   
    425429  strfcpy (buf, NONULL (Tempdir), sizeof (buf)); 
    426430  mutt_expand_path (buf, sizeof (buf)); 
     
    443447    { 
    444448      *period = '.'; 
    445       strcat (s, period); 
    446     } 
    447   } 
    448 } 
    449  
    450 /* This routine expands the filename given to match the format of the 
    451  * nametemplate given.  It returns various values based on what operations 
    452  * it performs. 
    453  * 
     449      sl = strlen(s); 
     450      strfcpy(s + sl, period, l - sl); 
     451    } 
     452  } 
     453} 
     454 
     455/* This routine will create a _temporary_ filename matching the 
     456 * name template given if this needs to be done. 
     457 *  
     458 * Please note that only the last path element of the 
     459 * template and/or the old file name will be used for the 
     460 * comparison and the temporary file name. 
     461 *  
    454462 * Returns 0 if oldfile is fine as is. 
    455463 * Returns 1 if newfile specified 
    456464 */ 
     465 
     466static void strnfcpy(char *d, char *s, size_t siz, size_t len) 
     467{ 
     468  if(len > siz) 
     469    len = siz - 1; 
     470  strfcpy(d, s, len); 
     471} 
    457472 
    458473int rfc1524_expand_filename (char *nametemplate, 
     
    461476                             size_t nflen) 
    462477{ 
    463   int z = 0; 
    464   int i = 0, j = 0; 
    465   int lmatch = TRUE; 
    466   int match = TRUE; 
    467   size_t len = 0; 
     478  int i, j, k, ps, r; 
    468479  char *s; 
    469  
     480  short lmatch = 0, rmatch = 0;  
     481  char left[_POSIX_PATH_MAX]; 
     482  char right[_POSIX_PATH_MAX]; 
     483   
    470484  newfile[0] = 0; 
    471485 
     486  /* first, ignore leading path components. 
     487   */ 
     488   
    472489  if (nametemplate && (s = strrchr (nametemplate, '/'))) 
    473490    nametemplate = s + 1; 
    474491 
    475492  if (oldfile && (s = strrchr (oldfile, '/'))) 
    476   { 
    477     len = s - oldfile + 1; 
    478     if (len > nflen) 
    479       len = nflen; 
    480     strfcpy (newfile, oldfile, len + 1); 
    481     oldfile += len; 
    482   } 
    483  
    484   /* If nametemplate is NULL, create a newfile from oldfile and return 0 */ 
     493    oldfile = s + 1; 
     494     
    485495  if (!nametemplate) 
    486496  { 
    487497    if (oldfile) 
    488498      strfcpy (newfile, oldfile, nflen); 
    489     mutt_adv_mktemp (newfile, nflen); 
     499  } 
     500  else if (!oldfile) 
     501  { 
     502    snprintf (newfile, nflen, nametemplate, "mutt"); 
     503  } 
     504  else /* oldfile && nametemplate */ 
     505  { 
     506 
     507    /* first, compare everything left from the "%s"  
     508     * (if there is one). 
     509     */ 
     510     
     511    lmatch = 1; ps = 0; 
     512    for(i = 0; nametemplate[i]; i++) 
     513    { 
     514      if(nametemplate[i] == '%' && nametemplate[i+1] == 's') 
     515      {  
     516        ps = 1; 
     517        break; 
     518      } 
     519 
     520      /* note that the following will _not_ read beyond oldfile's end. */ 
     521 
     522      if(lmatch && nametemplate[i] != oldfile[i]) 
     523        lmatch = 0; 
     524    } 
     525 
     526    if(ps) 
     527    { 
     528       
     529      /* If we had a "%s", check the rest. */ 
     530       
     531      /* now, for the right part: compare everything right from  
     532       * the "%s" to the final part of oldfile. 
     533       *  
     534       * The logic here is as follows: 
     535       *  
     536       * - We start reading from the end. 
     537       * - There must be a match _right_ from the "%s", 
     538       *   thus the i + 2.   
     539       * - If there was a left hand match, this stuff 
     540       *   must not be counted again.  That's done by the 
     541       *   condition (j >= (lmatch ? i : 0)). 
     542       */ 
     543       
     544      rmatch = 1; 
     545 
     546      for(r = 0, j = strlen(oldfile) - 1, k = strlen(nametemplate) - 1 ; 
     547          j >= (lmatch ? i : 0) && k >= i + 2; 
     548          j--, k--) 
     549      { 
     550        if(nametemplate[k] != oldfile[j]) 
     551        { 
     552          rmatch = 0; 
     553          break; 
     554        } 
     555      } 
     556       
     557      /* Now, check if we had a full match. */ 
     558       
     559      if(k >= i + 2) 
     560        rmatch = 0; 
     561       
     562      if(lmatch) *left = 0; 
     563      else strnfcpy(left, nametemplate, sizeof(left), i); 
     564       
     565      if(rmatch) *right = 0; 
     566      else strfcpy(right, nametemplate + i + 2, sizeof(right)); 
     567       
     568      snprintf(newfile, nflen, "%s%s%s", left, oldfile, right); 
     569    } 
     570    else 
     571    { 
     572      /* no "%s" in the name template. */ 
     573      strfcpy(newfile, nametemplate, nflen); 
     574    } 
     575  } 
     576   
     577  mutt_adv_mktemp(newfile, nflen); 
     578 
     579  if(rmatch && lmatch) 
    490580    return 0; 
    491   } 
    492  
    493   /* If oldfile is NULL, just return a newfile name */ 
    494   if (!oldfile) 
    495   { 
    496     snprintf (newfile, nflen, nametemplate, "mutt"); 
    497     mutt_adv_mktemp (newfile, nflen); 
    498     return 0; 
    499   } 
    500  
    501   /* Next, attempt to determine if the oldfile already matches nametemplate */ 
    502   /* Nametemplate is of the form pre%spost, only replace pre or post if 
    503    * they don't already match the oldfilename */ 
    504   /* Test pre */ 
    505  
    506   if ((s = strrchr (nametemplate, '%')) != NULL) 
    507   { 
    508     newfile[len] = '\0'; 
    509  
    510     z = s - nametemplate; 
    511  
    512     for (i = 0; i < z && i < nflen; i++) 
    513     { 
    514       if (oldfile[i] != nametemplate[i]) 
    515       { 
    516         lmatch=FALSE; 
    517         break; 
    518       } 
    519     } 
    520  
    521     if (!lmatch) 
    522     { 
    523       match = FALSE; 
    524       i = nflen - len; 
    525       if (i > z) 
    526         i = z; 
    527       strfcpy (newfile + len, nametemplate, i); 
    528     } 
    529  
    530     strfcpy (newfile + strlen (newfile),  
    531             oldfile, nflen - strlen (newfile)); 
    532  
    533     dprint (1, (debugfile,"template: %s, oldfile: %s, newfile: %s\n", 
    534               nametemplate, oldfile, newfile)); 
    535  
    536     /* test post */ 
    537     lmatch = TRUE; 
    538  
    539     for (z += 2, i = strlen (oldfile) - 1, j = strlen (nametemplate) - 1;  
    540         i && j > z; i--, j--) 
    541       if (oldfile[i] != nametemplate[j]) 
    542       { 
    543         lmatch = FALSE; 
    544         break; 
    545       } 
    546  
    547     if (!lmatch) 
    548     { 
    549       match = FALSE; 
    550       strfcpy (newfile + strlen (newfile), 
    551               nametemplate + z, nflen - strlen (newfile)); 
    552     } 
    553  
    554     if (match)  
    555       return 0; 
    556  
     581  else  
    557582    return 1; 
    558   } 
    559   else 
    560   { 
    561     /* no %s in nametemplate, graft unto path of oldfile */ 
    562     strfcpy (newfile, nametemplate, nflen); 
    563     return 1; 
    564   } 
    565 } 
    566  
    567 /* For nametemplate support, we may need to rename a file. 
    568  * If rfc1524_expand_command() is used on a recv'd message, then 
     583   
     584} 
     585 
     586/* If rfc1524_expand_command() is used on a recv'd message, then 
    569587 * the filename doesn't exist yet, but if its used while sending a message, 
    570588 * then we need to rename the existing file.