Re: Extending find(1) to support -printf

2008-09-13 Thread Ulrich Spoerlein
Pretty late to the game, but ...

On Mon, 08.09.2008 at 15:47:20 +0200, Oliver Fromme wrote:
 Jeremy Chadwick wrote:
  Equally as frustrating, mutt's backtick support will only honour the
  first line of input.  If a backticked command returns multiple lines,
  only the first is read; the rest are ignored.
 
 Well, you can convert back and forth between spaces
 and newlines with tr(1):
 
 echo * | tr ' ' '\n' | grep -v whatever | tr '\n' ' '

If your data is not very large, you can also fool xargs(1) into doing
the conversion for you

$ echo * | xargs -n1
and
$ ls -1 | xargs

 It's not pretty, but it should work.  Note that ls(1)
 prints one file name per line, so you can simplify the
 above line like this:
 
 ls | grep -v whatever | tr '\n' ' '
 
 By the way, I often use zsh in such cases.  It supports
 extended globbing, for example, the wildcard expression
 *~*.(gz|bz2) matches all files _except_ the ones that end
 with .gz or .bz2.

Indeed much more useful than fighting with find(1) and passing the file
lists around.

Cheers,
Ulrich Spoerlein
-- 
It is better to remain silent and be thought a fool,
than to speak, and remove all doubt.
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: Extending find(1) to support -printf

2008-09-08 Thread Oliver Fromme
Jeremy Chadwick wrote:
  On Fri, Sep 05, 2008 at 03:12:53AM -0700, Jeremy Chadwick wrote:
   Also, some folks on #bsdports asked why I was bothering with this in the
   first place: mutt supports backticks to run shell commands inside of
   a muttrc file.  See Building a list of mailboxes on the fly below:
   
   http://wiki.mutt.org/?ConfigTricks
   
   Note the find ... -printf '%h ' method.  I can accomplish (just
   about) the same using `echo $HOME/Maildir/*`, but if I want to
   exclude an entry, I can't use | grep -v, because mutt doesn't support
   pipes within backticks.  :-)
  
  Follow-up:
  
  mutt's backtick support does in fact respect pipes.  My echo|grep -v was
  doing exactly what I requested: the grep -v was removing all output of
  the echo, since echo returned the results in a space-delimited format,
  not one per line.  Hence, mailboxes was being executed without any
  arguments.
  
  Equally as frustrating, mutt's backtick support will only honour the
  first line of input.  If a backticked command returns multiple lines,
  only the first is read; the rest are ignored.

Well, you can convert back and forth between spaces
and newlines with tr(1):

echo * | tr ' ' '\n' | grep -v whatever | tr '\n' ' '

It's not pretty, but it should work.  Note that ls(1)
prints one file name per line, so you can simplify the
above line like this:

ls | grep -v whatever | tr '\n' ' '

By the way, I often use zsh in such cases.  It supports
extended globbing, for example, the wildcard expression
*~*.(gz|bz2) matches all files _except_ the ones that end
with .gz or .bz2.

Best regards
   Oliver

-- 
Oliver Fromme, secnetix GmbH  Co. KG, Marktplatz 29, 85567 Grafing b. M.
Handelsregister: Registergericht Muenchen, HRA 74606,  Geschäftsfuehrung:
secnetix Verwaltungsgesellsch. mbH, Handelsregister: Registergericht Mün-
chen, HRB 125758,  Geschäftsführer: Maik Bachmann, Olaf Erb, Ralf Gebhart

FreeBSD-Dienstleistungen, -Produkte und mehr:  http://www.secnetix.de/bsd

Perl is worse than Python because people wanted it worse.
-- Larry Wall
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to [EMAIL PROTECTED]


Extending find(1) to support -printf

2008-09-05 Thread Jeremy Chadwick
I've been working on $SUBJECT for the past few hours, and have managed
to implement a very crude subset of GNU find's features:

http://www.gnu.org/software/findutils/manual/html_node/find_html/Format-Directives.html#Format-Directives

I've implemented %f and %p (which appear identical to GNU find), and
some escaped characters.

Things I need help with, as string parsing in C has never been my forte
(which will become quite obvious):

1) Getting %h to behave like GNU find.  The GNU find code is
significantly different than ours.  As it stands, %h is broken.

2) find . -printf '\' results in odd output (SHELL=/usr/local/bin/bash
on my box).  Not sure why this is happening, but it's a big concern.

3) Security issues.  I believe use of a large number of formatting
variables could exceed the calloc()'d buffer (of MAXPATHLEN), causing
a segfault at bare minimum.  I'm not sure how to work around this.

Also, some folks on #bsdports asked why I was bothering with this in the
first place: mutt supports backticks to run shell commands inside of
a muttrc file.  See Building a list of mailboxes on the fly below:

http://wiki.mutt.org/?ConfigTricks

Note the find ... -printf '%h ' method.  I can accomplish (just
about) the same using `echo $HOME/Maildir/*`, but if I want to
exclude an entry, I can't use | grep -v, because mutt doesn't support
pipes within backticks.  :-)
  
-- 
| Jeremy Chadwickjdc at parodius.com |
| Parodius Networking   http://www.parodius.com/ |
| UNIX Systems Administrator  Mountain View, CA, USA |
| Making life hard for others since 1977.  PGP: 4BD6C0CB |

diff -ruN find.orig/extern.h find/extern.h
--- find.orig/extern.h  2006-05-14 13:23:00.0 -0700
+++ find/extern.h   2008-09-04 20:55:17.0 -0700
@@ -73,6 +73,7 @@
 creat_fc_nouser;
 creat_fc_perm;
 creat_fc_print;
+creat_fc_printf;
 creat_fc_regex;
 creat_fc_simple;
 creat_fc_size;
@@ -107,6 +108,7 @@
 exec_f f_perm;
 exec_f f_print;
 exec_f f_print0;
+exec_f f_printf;
 exec_f f_prune;
 exec_f f_regex;
 exec_f f_size;
diff -ruN find.orig/function.c find/function.c
--- find.orig/function.c2006-05-27 11:27:41.0 -0700
+++ find/function.c 2008-09-05 03:01:36.0 -0700
@@ -1272,6 +1272,86 @@
 /* c_print0 is the same as c_print */
 
 /*
+ * -printf functions --
+ *
+ * Always true, manipulates output based on printf()-like
+ * formatting characters.
+ */
+int
+f_printf(PLAN *plan, FTSENT *entry)
+{
+   char *scan;
+   char *outptr;
+   char *outidx;
+
+   if ((outptr = calloc(MAXPATHLEN, 1)) == NULL)
+   err(1, NULL);
+
+   outidx = outptr;
+
+   for (scan = plan-c_data; *scan; scan++) {
+   if (*scan == '%') {
+   if (scan[1] == 0) {
+   errx(1, missing format character);
+   }
+   else if (scan[1] == '%') {
+   *outidx++ = '%';
+   }
+   else if (scan[1] == 'f') {
+   strcpy(outidx, entry-fts_name);
+   outidx += entry-fts_namelen;
+   }
+   /* XXX - needs to behave like GNU find %h */
+   /*
+   else if (scan[1] == 'h') {
+   strcpy(outidx, entry-fts_path);
+   outidx += entry-fts_pathlen;
+   }
+   */
+   else if (scan[1] == 'p') {
+   strcpy(outidx, entry-fts_path);
+   outidx += entry-fts_pathlen;
+   }
+   scan++;
+   }
+   else if (*scan == '\\') {
+   if (scan[1] == '\\') {
+   *outidx++ = '\\';
+   }
+   else if (scan[1] == 'n') {
+   *outidx++ = '\n';
+   }
+   else if (scan[1] == 't') {
+   *outidx++ = '\t';
+   }
+   scan++;
+   }
+   else {
+   *outidx++ = *scan;
+   }
+   }
+
+   (void)printf(outptr);
+   free(outptr);
+   return 1;
+}
+
+PLAN *
+c_printf(OPTION *option, char ***argvp)
+{
+   char *argstring;
+   PLAN *new;
+
+   argstring = nextarg(option, argvp);
+   ftsoptions = ~FTS_NOSTAT;
+   isoutput = 1;
+
+   new = palloc(option);
+   new-c_data = argstring;
+   return new;
+}
+
+/*
  * -prune functions --
  *
  * Prune a portion of the hierarchy.
diff -ruN find.orig/option.c find/option.c
--- find.orig/option.c  2006-04-05 16:06:11.0 -0700

Re: Extending find(1) to support -printf

2008-09-05 Thread Jeremy Chadwick
On Fri, Sep 05, 2008 at 03:12:53AM -0700, Jeremy Chadwick wrote:
 Also, some folks on #bsdports asked why I was bothering with this in the
 first place: mutt supports backticks to run shell commands inside of
 a muttrc file.  See Building a list of mailboxes on the fly below:
 
 http://wiki.mutt.org/?ConfigTricks
 
 Note the find ... -printf '%h ' method.  I can accomplish (just
 about) the same using `echo $HOME/Maildir/*`, but if I want to
 exclude an entry, I can't use | grep -v, because mutt doesn't support
 pipes within backticks.  :-)

Follow-up:

mutt's backtick support does in fact respect pipes.  My echo|grep -v was
doing exactly what I requested: the grep -v was removing all output of
the echo, since echo returned the results in a space-delimited format,
not one per line.  Hence, mailboxes was being executed without any
arguments.

Equally as frustrating, mutt's backtick support will only honour the
first line of input.  If a backticked command returns multiple lines,
only the first is read; the rest are ignored.  This makes using BSD find
annoying, since find always outputs results terminated with a newline.
One of my peers uses find | perl -ne 'chomp; print =, $_,  ' to deal
with this limit, which is quite disgusting.

I realise there are workarounds for the dilemma (e.g. write a shell
script that provides the exact output needed), but it seems like one
could kill two birds with one stone by extending BSD find to support
-printf, which does not output a newline unless \n is used within the
output formatting.  (This also explains why the Mutt Wiki entry uses
-printf '%h ', note the space.)

-- 
| Jeremy Chadwickjdc at parodius.com |
| Parodius Networking   http://www.parodius.com/ |
| UNIX Systems Administrator  Mountain View, CA, USA |
| Making life hard for others since 1977.  PGP: 4BD6C0CB |

___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: Extending find(1) to support -printf

2008-09-05 Thread Jonathan McKeown
On Friday 05 September 2008 16:39, Jeremy Chadwick wrote:

 Equally as frustrating, mutt's backtick support will only honour the
 first line of input.  If a backticked command returns multiple lines,
 only the first is read; the rest are ignored.  This makes using BSD find
 annoying, since find always outputs results terminated with a newline.
 One of my peers uses find | perl -ne 'chomp; print =, $_,  ' to deal
 with this limit, which is quite disgusting.

It is, especially when you consider find ... | xargs (or find ... -print0 | 
xargs -0 if your filenames might cause problems (embedded spaces etc)).

Jonathan
___
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to [EMAIL PROTECTED]