Make -n combine with -bP to inhibit names
authorPhil Pennock <pdp@exim.org>
Fri, 1 Jun 2012 08:29:39 +0000 (04:29 -0400)
committerPhil Pennock <pdp@exim.org>
Fri, 1 Jun 2012 08:29:39 +0000 (04:29 -0400)
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/src/exim.c
src/src/functions.h
src/src/readconf.c

index 9637b51..61cdc1e 100644 (file)
@@ -2937,6 +2937,7 @@ use the &'exim_dbmbuild'& utility, or some other means, to rebuild alias files
 if this is required. If the &%bi_command%& option is not set, calling Exim with
 &%-bi%& is a no-op.
 
+.new
 .vitem &%-bI:help%&
 .oindex "&%-bI:help%&"
 .cindex "querying exim information"
@@ -2955,6 +2956,7 @@ useful for ManageSieve (RFC 5804) implementations, in providing that protocol's
 &`SIEVE`& capability response line.  As the precise list may depend upon
 compile-time build options, which this option will adapt to, this is the only
 way to guarantee a correct response.
+.wen
 
 .vitem &%-bm%&
 .oindex "&%-bm%&"
@@ -3069,6 +3071,12 @@ configuration file is output.
 If a list of configuration files was supplied, the value that is output here
 is the name of the file that was actually used.
 
+.new
+.cindex "options" "hiding name of"
+If the &%-n%& flag is given, then for most modes of &%-bP%& operation the
+name will not be output.
+.wen
+
 .cindex "daemon" "process id (pid)"
 .cindex "pid (process id)" "of daemon"
 If &%log_file_path%& or &%pid_file_path%& are given, the names of the
@@ -3930,9 +3938,9 @@ for that message.
 
 .vitem &%-n%&
 .oindex "&%-n%&"
-.cindex "Sendmail compatibility" "&%-n%& option ignored"
-This option is interpreted by Sendmail to mean &"no aliasing"&. It is ignored
-by Exim.
+This option is interpreted by Sendmail to mean &"no aliasing"&.
+For normal modes of operation, it is ignored by Exim.
+When combined with &%-bP%& it suppresses the name of an option from being output.
 
 .vitem &%-O%&&~<&'data'&>
 .oindex "&%-O%&"
index d79f4ee..533ce50 100644 (file)
@@ -6,6 +6,9 @@ Exim version 4.81
 
 PP/01 Add -bI: framework, and -bI:sieve for querying sieve capabilities.
 
+PP/02 Make -n do something, by making it not do something.
+      When combined with -bP, the name of an option is not output.
+
 
 Exim version 4.80
 -----------------
index 71f1e8e..5088a24 100644 (file)
@@ -15,6 +15,11 @@ Version 4.81
     query this to establish the correct list to include in the protocol's
     SIEVE capability line.
 
+ 2. If the -n option is combined with the -bP option, then the name of an
+    emitted option is not output, only the value (if visible to you).
+    For instance, "exim -n -bP pid_file_path" should just emit a pathname
+    followed by a newline, and no other text.
+
 
 Version 4.80
 ------------
index ff6b4dd..9f6f3d8 100644 (file)
@@ -1431,6 +1431,7 @@ BOOL checking = FALSE;
 BOOL count_queue = FALSE;
 BOOL expansion_test = FALSE;
 BOOL extract_recipients = FALSE;
+BOOL flag_n = FALSE;
 BOOL forced_delivery = FALSE;
 BOOL f_end_dot = FALSE;
 BOOL deliver_give_up = FALSE;
@@ -2764,10 +2765,12 @@ for (i = 1; i < argc; i++)
     break;
 
 
-    /* -n: This means "don't alias" in sendmail, apparently. Just ignore
-    it. */
+    /* -n: This means "don't alias" in sendmail, apparently.
+    For normal invocations, it has no effect.
+    It may affect some other options. */
 
     case 'n':
+    flag_n = TRUE;
     break;
 
     /* -O: Just ignore it. In sendmail, apparently -O option=value means set
@@ -4288,11 +4291,12 @@ if (test_retry_arg >= 0)
   }
 
 /* Handle a request to list one or more configuration options */
+/* If -n was set, we suppress some information */
 
 if (list_options)
   {
   set_process_info("listing variables");
-  if (recipients_arg >= argc) readconf_print(US"all", NULL);
+  if (recipients_arg >= argc) readconf_print(US"all", NULL, flag_n);
     else for (i = recipients_arg; i < argc; i++)
       {
       if (i < argc - 1 &&
@@ -4301,10 +4305,10 @@ if (list_options)
            Ustrcmp(argv[i], "authenticator") == 0 ||
            Ustrcmp(argv[i], "macro") == 0))
         {
-        readconf_print(argv[i+1], argv[i]);
+        readconf_print(argv[i+1], argv[i], flag_n);
         i++;
         }
-      else readconf_print(argv[i], NULL);
+      else readconf_print(argv[i], NULL, flag_n);
       }
   exim_exit(EXIT_SUCCESS);
   }
index 29e7db2..fa9d558 100644 (file)
@@ -228,7 +228,7 @@ extern void    readconf_driver_init(uschar *, driver_instance **,
                  driver_info *, int, void *, int, optionlist *, int);
 extern uschar *readconf_find_option(void *);
 extern void    readconf_main(void);
-extern void    readconf_print(uschar *, uschar *);
+extern void    readconf_print(uschar *, uschar *, BOOL);
 extern uschar *readconf_printtime(int);
 extern uschar *readconf_readname(uschar *, int, uschar *);
 extern int     readconf_readtime(uschar *, int, BOOL);
index c3ffe4f..568990a 100644 (file)
@@ -2150,13 +2150,14 @@ Arguments:
                    resides.
   oltop          points to the option list in which ol exists
   last           one more than the offset of the last entry in optop
+  no_labels      do not show "foo = " at the start.
 
 Returns:         nothing
 */
 
 static void
 print_ol(optionlist *ol, uschar *name, void *options_block,
-  optionlist *oltop, int last)
+  optionlist *oltop, int last, BOOL no_labels)
 {
 struct passwd *pw;
 struct group *gr;
@@ -2178,7 +2179,11 @@ if (ol == NULL)
 
 if (!admin_user && (ol->type & opt_secure) != 0)
   {
-  printf("%s = <value not displayable>\n", name);
+  const char * const hidden = "<value not displayable>";
+  if (no_labels)
+    printf("%s\n", hidden);
+  else
+    printf("%s = %s\n", name, hidden);
   return;
   }
 
@@ -2197,11 +2202,13 @@ switch(ol->type & opt_mask)
   case opt_stringptr:
   case opt_rewrite:        /* Show the text value */
   s = *((uschar **)value);
-  printf("%s = %s\n", name, (s == NULL)? US"" : string_printing2(s, FALSE));
+  if (!no_labels) printf("%s = ", name);
+  printf("%s\n", (s == NULL)? US"" : string_printing2(s, FALSE));
   break;
 
   case opt_int:
-  printf("%s = %d\n", name, *((int *)value));
+  if (!no_labels) printf("%s = ", name);
+  printf("%d\n", *((int *)value));
   break;
 
   case opt_mkint:
@@ -2216,23 +2223,30 @@ switch(ol->type & opt_mask)
         c = 'M';
         x >>= 10;
         }
-      printf("%s = %d%c\n", name, x, c);
+      if (!no_labels) printf("%s = ", name);
+      printf("%d%c\n", x, c);
+      }
+    else
+      {
+      if (!no_labels) printf("%s = ", name);
+      printf("%d\n", x);
       }
-    else printf("%s = %d\n", name, x);
     }
   break;
 
   case opt_Kint:
     {
     int x = *((int *)value);
-    if (x == 0) printf("%s = 0\n", name);
-      else if ((x & 1023) == 0) printf("%s = %dM\n", name, x >> 10);
-        else printf("%s = %dK\n", name, x);
+    if (!no_labels) printf("%s = ", name);
+    if (x == 0) printf("0\n");
+      else if ((x & 1023) == 0) printf("%dM\n", x >> 10);
+        else printf("%dK\n", x);
     }
   break;
 
   case opt_octint:
-  printf("%s = %#o\n", name, *((int *)value));
+  if (!no_labels) printf("%s = ", name);
+  printf("%#o\n", *((int *)value));
   break;
 
   /* Can be negative only when "unset", in which case integer */
@@ -2244,7 +2258,8 @@ switch(ol->type & opt_mask)
     int d = 100;
     if (x < 0) printf("%s =\n", name); else
       {
-      printf("%s = %d.", name, x/1000);
+      if (!no_labels) printf("%s = ", name);
+      printf("%d.", x/1000);
       do
         {
         printf("%d", f/d);
@@ -2270,7 +2285,8 @@ switch(ol->type & opt_mask)
       if (options_block != NULL)
         value2 = (void *)((uschar *)options_block + (long int)value2);
       s = *((uschar **)value2);
-      printf("%s = %s\n", name, (s == NULL)? US"" : string_printing(s));
+      if (!no_labels) printf("%s = ", name);
+      printf("%s\n", (s == NULL)? US"" : string_printing(s));
       break;
       }
     }
@@ -2278,14 +2294,15 @@ switch(ol->type & opt_mask)
   /* Else fall through */
 
   case opt_uid:
+  if (!no_labels) printf("%s = ", name);
   if (! *get_set_flag(name, oltop, last, options_block))
-    printf("%s =\n", name);
+    printf("\n");
   else
     {
     pw = getpwuid(*((uid_t *)value));
     if (pw == NULL)
-      printf("%s = %ld\n", name, (long int)(*((uid_t *)value)));
-    else printf("%s = %s\n", name, pw->pw_name);
+      printf("%ld\n", (long int)(*((uid_t *)value)));
+    else printf("%s\n", pw->pw_name);
     }
   break;
 
@@ -2302,7 +2319,8 @@ switch(ol->type & opt_mask)
       if (options_block != NULL)
         value2 = (void *)((uschar *)options_block + (long int)value2);
       s = *((uschar **)value2);
-      printf("%s = %s\n", name, (s == NULL)? US"" : string_printing(s));
+      if (!no_labels) printf("%s = ", name);
+      printf("%s\n", (s == NULL)? US"" : string_printing(s));
       break;
       }
     }
@@ -2310,31 +2328,34 @@ switch(ol->type & opt_mask)
   /* Else fall through */
 
   case opt_gid:
+  if (!no_labels) printf("%s = ", name);
   if (! *get_set_flag(name, oltop, last, options_block))
-    printf("%s =\n", name);
+    printf("\n");
   else
     {
     gr = getgrgid(*((int *)value));
     if (gr == NULL)
-       printf("%s = %ld\n", name, (long int)(*((int *)value)));
-    else printf("%s = %s\n", name, gr->gr_name);
+       printf("%ld\n", (long int)(*((int *)value)));
+    else printf("%s\n", gr->gr_name);
     }
   break;
 
   case opt_uidlist:
   uidlist = *((uid_t **)value);
-  printf("%s =", name);
+  if (!no_labels) printf("%s =", name);
   if (uidlist != NULL)
     {
     int i;
     uschar sep = ' ';
+    if (no_labels) sep = '\0';
     for (i = 1; i <= (int)(uidlist[0]); i++)
       {
       uschar *name = NULL;
       pw = getpwuid(uidlist[i]);
       if (pw != NULL) name = US pw->pw_name;
-      if (name != NULL) printf("%c%s", sep, name);
-        else printf("%c%ld", sep, (long int)(uidlist[i]));
+      if (sep != '\0') printf("%c", sep);
+      if (name != NULL) printf("%s", name);
+        else printf("%ld", (long int)(uidlist[i]));
       sep = ':';
       }
     }
@@ -2343,18 +2364,20 @@ switch(ol->type & opt_mask)
 
   case opt_gidlist:
   gidlist = *((gid_t **)value);
-  printf("%s =", name);
+  if (!no_labels) printf("%s =", name);
   if (gidlist != NULL)
     {
     int i;
     uschar sep = ' ';
+    if (no_labels) sep = '\0';
     for (i = 1; i <= (int)(gidlist[0]); i++)
       {
       uschar *name = NULL;
       gr = getgrgid(gidlist[i]);
       if (gr != NULL) name = US gr->gr_name;
-      if (name != NULL) printf("%c%s", sep, name);
-        else printf("%c%ld", sep, (long int)(gidlist[i]));
+      if (sep != '\0') printf("%c", sep);
+      if (name != NULL) printf("%s", name);
+        else printf("%ld", (long int)(gidlist[i]));
       sep = ':';
       }
     }
@@ -2362,14 +2385,15 @@ switch(ol->type & opt_mask)
   break;
 
   case opt_time:
-  printf("%s = %s\n", name, readconf_printtime(*((int *)value)));
+  if (!no_labels) printf("%s = ", name);
+  printf("%s\n", readconf_printtime(*((int *)value)));
   break;
 
   case opt_timelist:
     {
     int i;
     int *list = (int *)value;
-    printf("%s = ", name);
+    if (!no_labels) printf("%s = ", name);
     for (i = 0; i < list[1]; i++)
       printf("%s%s", (i == 0)? "" : ":", readconf_printtime(list[i+2]));
     printf("\n");
@@ -2392,7 +2416,8 @@ switch(ol->type & opt_mask)
     s = *((uschar **)value2);
     if (s != NULL)
       {
-      printf("%s = %s\n", name, string_printing(s));
+      if (!no_labels) printf("%s = ", name);
+      printf("%s\n", string_printing(s));
       break;
       }
     /* s == NULL => string not set; fall through */
@@ -2438,12 +2463,13 @@ driver whose options are to be printed.
 Arguments:
   name        option name if type == NULL; else driver name
   type        NULL or driver type name, as described above
+  no_labels   avoid the "foo = " at the start of an item
 
 Returns:      nothing
 */
 
 void
-readconf_print(uschar *name, uschar *type)
+readconf_print(uschar *name, uschar *type, BOOL no_labels)
 {
 BOOL names_only = FALSE;
 optionlist *ol;
@@ -2470,8 +2496,11 @@ if (type == NULL)
       if (t != NULL)
         {
         found = TRUE;
-        printf("%slist %s = %s\n", types[i], name+1,
-          ((namedlist_block *)(t->data.ptr))->string);
+        if (no_labels)
+          printf("%s\n", ((namedlist_block *)(t->data.ptr))->string);
+        else
+          printf("%slist %s = %s\n", types[i], name+1,
+            ((namedlist_block *)(t->data.ptr))->string);
         }
       }
 
@@ -2494,7 +2523,9 @@ if (type == NULL)
          ol < optionlist_config + optionlist_config_size; ol++)
       {
       if ((ol->type & opt_hidden) == 0)
-        print_ol(ol, US ol->name, NULL, optionlist_config, optionlist_config_size);
+        print_ol(ol, US ol->name, NULL,
+            optionlist_config, optionlist_config_size,
+            no_labels);
       }
     return;
     }
@@ -2508,7 +2539,7 @@ if (type == NULL)
          ol < local_scan_options + local_scan_options_count; ol++)
       {
       print_ol(ol, US ol->name, NULL, local_scan_options,
-        local_scan_options_count);
+        local_scan_options_count, no_labels);
       }
     #endif
     return;
@@ -2568,7 +2599,7 @@ if (type == NULL)
   else
     {
     print_ol(find_option(name, optionlist_config, optionlist_config_size),
-      name, NULL, optionlist_config, optionlist_config_size);
+      name, NULL, optionlist_config, optionlist_config_size, no_labels);
     return;
     }
   }
@@ -2641,14 +2672,14 @@ for (; d != NULL; d = d->next)
   for (ol = ol2; ol < ol2 + size; ol++)
     {
     if ((ol->type & opt_hidden) == 0)
-      print_ol(ol, US ol->name, d, ol2, size);
+      print_ol(ol, US ol->name, d, ol2, size, no_labels);
     }
 
   for (ol = d->info->options;
        ol < d->info->options + *(d->info->options_count); ol++)
     {
     if ((ol->type & opt_hidden) == 0)
-      print_ol(ol, US ol->name, d, d->info->options, *(d->info->options_count));
+      print_ol(ol, US ol->name, d, d->info->options, *(d->info->options_count), no_labels);
     }
   if (name != NULL) return;
   }