<<< Date Index >>>     <<< Thread Index >>>

Re: length of path variables



Hello Bertrand,

On Tue, Nov 30, 2010 at 03:46:18PM +0100, Bertrand Yvain wrote:
> There is a tricky part with using PATH_MAX.  Quoting POSIX 2008 [1]:
> 
> : The values in the following list may be constants within an
> : implementation or may vary from one pathname to another. For example,
> : file systems or directories may have different characteristics.
> 
> : {PATH_MAX}
> :   Maximum number of bytes the implementation will store as a pathname
> :   in a user-supplied buffer of unspecified size, including the
> :   terminating null character. Minimum number the implementation will
> :   accept as the maximum number of bytes in a pathname.
> :   Minimum Acceptable Value: {_POSIX_PATH_MAX}
> :   [XSI] Minimum Acceptable Value: {_XOPEN_PATH_MAX}
> 
> So PATH_MAX is not really compatible with static/automatic allocation
> unless path are consistently absolute or relative to the same directory.
> 
> I see _POSIX_PATH_MAX as the safe choice (without XSI conformance).

Thanks for the detailed information!
Nonetheless PATH_MAX is used in mutt for static/automatic allocation in
a few places. I implemented both ideas and attached the patches.
What do you think?


Greetings,
Johannes
diff -r 57568da7d9aa doc/makedoc.c
--- a/doc/makedoc.c     Wed Oct 13 07:38:30 2010 -0700
+++ b/doc/makedoc.c     Wed Dec 01 14:07:09 2010 +0100
@@ -358,7 +358,8 @@
   DT_RX,
   DT_MAGIC,
   DT_SYN,
-  DT_ADDR
+  DT_ADDR,
+  DT_CMD
 };
 
 struct 
@@ -379,6 +380,7 @@
   { "DT_MAGIC",        "folder magic" },
   { "DT_SYN",  NULL },
   { "DT_ADDR", "e-mail address" },
+  { "DT_CMD",  "path"          },
   { NULL, NULL }
 };
     
@@ -514,6 +516,7 @@
     case DT_RX:
     case DT_ADDR:
     case DT_PATH:
+    case DT_CMD:
     {
       if (!strcmp (s, "0"))
        break;
@@ -652,7 +655,8 @@
     /* configuration file */
     case F_CONF:
     {
-      if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == 
DT_PATH)
+      if (type == DT_STR || type == DT_RX || type == DT_ADDR ||
+          type == DT_PATH || type == DT_CMD)
       {
        fprintf (out, "\n# set %s=\"", varname);
        conf_print_strval (val, out);
@@ -663,7 +667,8 @@
       
       fprintf (out, "\n#\n# Name: %s", varname);
       fprintf (out, "\n# Type: %s", type2human (type));
-      if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == 
DT_PATH)
+      if (type == DT_STR || type == DT_RX || type == DT_ADDR ||
+          type == DT_PATH || type == DT_CMD)
       {
        fputs ("\n# Default: \"", out);
        conf_print_strval (val, out);
@@ -682,7 +687,8 @@
       fprintf (out, "\n.TP\n.B %s\n", varname);
       fputs (".nf\n", out);
       fprintf (out, "Type: %s\n", type2human (type));
-      if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == 
DT_PATH)
+      if (type == DT_STR || type == DT_RX || type == DT_ADDR ||
+          type == DT_PATH || type == DT_CMD)
       {
        fputs ("Default: \\(lq", out);
        man_print_strval (val, out);
@@ -709,7 +715,8 @@
       fprintf (out, "</title>\n<literallayout>Type: %s", type2human (type));
 
       
-      if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == 
DT_PATH)
+      if (type == DT_STR || type == DT_RX || type == DT_ADDR ||
+          type == DT_PATH || type == DT_CMD)
       {
        if (val && *val)
        {
diff -r 57568da7d9aa init.c
--- a/init.c    Wed Oct 13 07:38:30 2010 -0700
+++ b/init.c    Wed Dec 01 14:07:09 2010 +0100
@@ -347,6 +347,7 @@
       FREE (&pp->rx);
     }
     break;
+  case DT_CMD:
   case DT_PATH:
   case DT_STR:
     FREE ((char**)p->data);            /* __FREE_CHECKED__ */
@@ -1499,6 +1500,7 @@
       if (!p->init && *((char **) p->data))
         p->init = (unsigned long) safe_strdup (* ((char **) p->data));
       break;
+    case DT_CMD:
     case DT_PATH:
       if (!p->init && *((char **) p->data))
       {
@@ -1533,6 +1535,16 @@
     case DT_STR:
       mutt_str_replace ((char **) p->data, (char *) p->init); 
       break;
+    case DT_CMD:
+      FREE((char **) p->data);         /* __FREE_CHECKED__ */
+      if (p->init)
+      {
+       char cmd[LONG_STRING];
+       strfcpy (cmd, (char *) p->init, sizeof (cmd));
+       mutt_expand_path (cmd, sizeof (cmd));
+       *((char **) p->data) = safe_strdup (cmd);
+      }
+      break;
     case DT_PATH:
       FREE((char **) p->data);         /* __FREE_CHECKED__ */
       if (p->init)
@@ -1691,7 +1703,7 @@
 {
   int query, unset, inv, reset, r = 0;
   int idx = -1;
-  char *p, scratch[_POSIX_PATH_MAX];
+  char *p, scratch[_POSIX_PATH_MAX], cmd_scratch[LONG_STRING];
   char* myvar;
 
   while (MoreArgs (s))
@@ -1816,6 +1828,7 @@
        set_option (MuttVars[idx].data);
     }
     else if (myvar || DTYPE (MuttVars[idx].type) == DT_STR ||
+            DTYPE (MuttVars[idx].type) == DT_CMD ||
             DTYPE (MuttVars[idx].type) == DT_PATH ||
             DTYPE (MuttVars[idx].type) == DT_ADDR)
     {
@@ -1855,7 +1868,8 @@
          rfc822_write_address (_tmp, sizeof (_tmp), *((ADDRESS **) 
MuttVars[idx].data), 0);
          val = _tmp;
        }
-       else if (DTYPE (MuttVars[idx].type) == DT_PATH)
+       else if (DTYPE (MuttVars[idx].type) == DT_PATH ||
+            DTYPE (MuttVars[idx].type) == DT_CMD)
        {
          _tmp[0] = '\0';
          strfcpy (_tmp, NONULL(*((char **) MuttVars[idx].data)), sizeof 
(_tmp));
@@ -1889,6 +1903,14 @@
           FREE (&myvar);
          myvar="don't resort";
         }
+        else if (DTYPE (MuttVars[idx].type) == DT_CMD)
+        {
+         FREE ((void *) MuttVars[idx].data);           /* __FREE_CHECKED__ */
+
+         strfcpy (cmd_scratch, tmp->data, sizeof (cmd_scratch));
+         mutt_expand_path (cmd_scratch, sizeof (cmd_scratch));
+         *((char **) MuttVars[idx].data) = safe_strdup (cmd_scratch);
+        }
         else if (DTYPE (MuttVars[idx].type) == DT_PATH)
         {
          /* MuttVars[idx].data is already 'char**' (or some 'void**') or... 
@@ -2637,11 +2659,13 @@
   tmp[0] = '\0';
 
   if ((DTYPE(MuttVars[idx].type) == DT_STR) ||
+      (DTYPE(MuttVars[idx].type) == DT_CMD) ||
       (DTYPE(MuttVars[idx].type) == DT_PATH) ||
       (DTYPE(MuttVars[idx].type) == DT_RX))
   {
     strfcpy (tmp, NONULL (*((char **) MuttVars[idx].data)), sizeof (tmp));
-    if (DTYPE (MuttVars[idx].type) == DT_PATH)
+    if (DTYPE (MuttVars[idx].type) == DT_PATH ||
+        DTYPE (MuttVars[idx].type) == DT_CMD)
       mutt_pretty_mailbox (tmp, sizeof (tmp));
   }
   else if (DTYPE (MuttVars[idx].type) == DT_ADDR)
diff -r 57568da7d9aa init.h
--- a/init.h    Wed Oct 13 07:38:30 2010 -0700
+++ b/init.h    Wed Dec 01 14:07:09 2010 +0100
@@ -38,6 +38,7 @@
 #define DT_MAGIC       8 /* mailbox type */
 #define DT_SYN         9 /* synonym for another variable */
 #define DT_ADDR               10 /* e-mail address */
+#define DT_CMD        11 /* a command */
 
 #define DTYPE(x) ((x) & DT_MASK)
 
@@ -607,7 +608,7 @@
   ** If this option is \fIset\fP, mutt's received-attachments menu will not 
show the subparts of
   ** individual messages in a multipart/digest.  To see these subparts, press 
``v'' on that menu.
   */
-  { "display_filter",  DT_PATH, R_PAGER, UL &DisplayFilter, UL "" },
+  { "display_filter",  DT_CMD, R_PAGER, UL &DisplayFilter, UL "" },
   /*
   ** .pp
   ** When set, specifies a command used to filter messages.  When a message
@@ -615,7 +616,7 @@
   ** filtered message is read from the standard output.
   */
 #if defined(DL_STANDALONE) && defined(USE_DOTLOCK)
-  { "dotlock_program",  DT_PATH, R_NONE, UL &MuttDotlock, UL BINDIR 
"/mutt_dotlock" },
+  { "dotlock_program",  DT_CMD, R_NONE, UL &MuttDotlock, UL BINDIR 
"/mutt_dotlock" },
   /*
   ** .pp
   ** Contains the path of the \fCmutt_dotlock(8)\fP binary to be used by
@@ -681,7 +682,7 @@
   { "edit_hdrs",       DT_SYN,  R_NONE, UL "edit_headers", 0 },
   /*
   */
-  { "editor",          DT_PATH, R_NONE, UL &Editor, 0 },
+  { "editor",          DT_CMD, R_NONE, UL &Editor, 0 },
   /*
   ** .pp
   ** This variable specifies which editor is used by mutt.
@@ -1311,7 +1312,7 @@
   ** Note that these expandos are supported in
   ** ``$save-hook'', ``$fcc-hook'' and ``$fcc-save-hook'', too.
   */
-  { "ispell",          DT_PATH, R_NONE, UL &Ispell, UL ISPELL },
+  { "ispell",          DT_CMD, R_NONE, UL &Ispell, UL ISPELL },
   /*
   ** .pp
   ** How to invoke ispell (GNU's spell-checking software).
@@ -1559,7 +1560,7 @@
   ** .dt %a .dd The remailer's e-mail address.
   ** .de
   */
-  { "mixmaster",       DT_PATH, R_NONE, UL &Mixmaster, UL MIXMASTER },
+  { "mixmaster",       DT_CMD, R_NONE, UL &Mixmaster, UL MIXMASTER },
   /*
   ** .pp
   ** This variable contains the path to the Mixmaster binary on your
@@ -1592,7 +1593,7 @@
    ** See also $$read_inc, $$write_inc and $$net_inc.
    */
 #endif
-  { "pager",           DT_PATH, R_NONE, UL &Pager, UL "builtin" },
+  { "pager",           DT_CMD, R_NONE, UL &Pager, UL "builtin" },
   /*
   ** .pp
   ** This variable specifies which pager you would like to use to view
@@ -2135,7 +2136,7 @@
   ** This is set to ``ask-no'' by default, because some people
   ** accidentally hit ``p'' often.
   */
-  { "print_command",   DT_PATH, R_NONE, UL &PrintCmd, UL "lpr" },
+  { "print_command",   DT_CMD, R_NONE, UL &PrintCmd, UL "lpr" },
   /*
   ** .pp
   ** This specifies the command pipe that should be used to print messages.
@@ -2175,7 +2176,7 @@
   ** than returning to the index menu.  If \fIunset\fP, Mutt will return to the
   ** index menu when the external pager exits.
   */
-  { "query_command",   DT_PATH, R_NONE, UL &QueryCmd, UL "" },
+  { "query_command",   DT_CMD, R_NONE, UL &QueryCmd, UL "" },
   /*
   ** .pp
   ** This specifies the command Mutt will use to make external address
@@ -2485,7 +2486,7 @@
   ** In case the text cannot be converted into one of these exactly,
   ** mutt uses $$charset as a fallback.
   */
-  { "sendmail",                DT_PATH, R_NONE, UL &Sendmail, UL SENDMAIL " 
-oem -oi" },
+  { "sendmail",                DT_CMD, R_NONE, UL &Sendmail, UL SENDMAIL " 
-oem -oi" },
   /*
   ** .pp
   ** Specifies the program and arguments used to deliver mail sent by Mutt.
@@ -2509,7 +2510,7 @@
   ** process will be put in a temporary file.  If there is some error, you
   ** will be informed as to where to find the output.
   */
-  { "shell",           DT_PATH, R_NONE, UL &Shell, 0 },
+  { "shell",           DT_CMD, R_NONE, UL &Shell, 0 },
   /*
   ** .pp
   ** Command to use when spawning a subshell.  By default, the user's login
@@ -3307,7 +3308,7 @@
   ** messages, indicating which version of mutt was used for composing
   ** them.
   */
-  { "visual",          DT_PATH, R_NONE, UL &Visual, 0 },
+  { "visual",          DT_CMD, R_NONE, UL &Visual, 0 },
   /*
   ** .pp
   ** Specifies the visual editor to invoke when the ``\fC~v\fP'' command is
diff -r 57568da7d9aa muttlib.c
--- a/muttlib.c Wed Oct 13 07:38:30 2010 -0700
+++ b/muttlib.c Wed Dec 01 14:07:09 2010 +0100
@@ -388,7 +388,7 @@
 {
   char p[_POSIX_PATH_MAX] = "";
   char q[_POSIX_PATH_MAX] = "";
-  char tmp[_POSIX_PATH_MAX];
+  char tmp[LONG_STRING];
   char *t;
 
   char *tail = ""; 
diff -r 57568da7d9aa init.c
--- a/init.c    Wed Oct 13 07:38:30 2010 -0700
+++ b/init.c    Wed Dec 01 14:07:44 2010 +0100
@@ -1537,7 +1537,7 @@
       FREE((char **) p->data);         /* __FREE_CHECKED__ */
       if (p->init)
       {
-       char path[_POSIX_PATH_MAX];
+       char path[LONG_STRING];
        strfcpy (path, (char *) p->init, sizeof (path));
        mutt_expand_path (path, sizeof (path));
        *((char **) p->data) = safe_strdup (path);
@@ -1691,7 +1691,7 @@
 {
   int query, unset, inv, reset, r = 0;
   int idx = -1;
-  char *p, scratch[_POSIX_PATH_MAX];
+  char *p, scratch[LONG_STRING];
   char* myvar;
 
   while (MoreArgs (s))
diff -r 57568da7d9aa muttlib.c
--- a/muttlib.c Wed Oct 13 07:38:30 2010 -0700
+++ b/muttlib.c Wed Dec 01 14:07:44 2010 +0100
@@ -388,7 +388,7 @@
 {
   char p[_POSIX_PATH_MAX] = "";
   char q[_POSIX_PATH_MAX] = "";
-  char tmp[_POSIX_PATH_MAX];
+  char tmp[LONG_STRING];
   char *t;
 
   char *tail = ""; 

Attachment: pgpVcHzPG5D8U.pgp
Description: PGP signature