Add in dummy AC_CONFIG_HEADERS("") line.
[fvwm-themes.git] / bin / fvwm-themes-com.in
bloba7cb33fd64c3f7e85f335d2961d4bd922e379d50
1 #!@PERL@ -w
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 #-----------------------------------------------------------------------------
19 # Copyright 2000, Olivier Chapuis
20 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23 # Filter this script to pod2man to get a man page:
24 #   pod2man -c "Fvwm Utility" fvwm-themes-com | nroff -man | less -e
25 #-----------------------------------------------------------------------------
27 use Getopt::Long;
29 my $version = '@VERSION@';
30 my $fvwmVersion = '@FVWM_VERSION@';
32 my $scriptName = ($0 =~ m:([^/]+)$:, $1);
33 my $message = "";
34 my $lockAndGet = 0;
35 my $getBuf = 0;
36 my $line = 0;
37 my $name = "";
38 my $clearBuf = 0;
39 my $optBufferName = "";
40 my $mainDir = $ENV{'FVWM_USERDIR'};
41 my $l;
42 # Nbr of 1/10 of second we spent to create a fifo (because an arbitrairy
43 # nbr of "Script" can ask question to a given "?" programs can) 
44 my $mkFifoTimeOut = 100;
46 chdir($mainDir) || die "No FvwmConfigHome $mainDir";
48 GetOptions(
49         "help"          => \&showHelp,
50         "version"       => \&showVersion,
51         "name=s"        => \$name,
52         "message=s"     => \$message,
53         "lock-and-get"  => \$lockAndGet,
54         "get-buffer"    => \$getBuf,
55         "buffer-name=s" => \$optBufferName,
56         "clear-buffer"  => \$clearBuf,
57         "line=i"        => \$line
58 ) || wrongUsage();
60 my $bufFile = ".tmp-com-buf-$name";
61 $bufFile = ".tmp-com-buf-$optBufferName" if ($optBufferName ne "");
63 if ($getBuf) {
64         $l = 0; $line-- if ($line > 0);
65         open(IN,"$bufFile") || die "cannot open $bufFile";
66         while(<IN>) {
67                 if ($line == $l || !$line) { print $_; } 
68                 $l++;
69         }
70         close(IN);
73 if ($clearBuf) { unlink($bufFile); }
75 if ($message ne "") {
77         my $outFifo = ".tmp-com-out-$name";
78         my $inFifo = ".tmp-com-in-$name";
79         my $lockFifo =".tmp-com-lock-$name";
80         my $done = 0;
81         my $i = 0;
83         # Nbr of second we wait for "?" to start and go to its com loop
84         my $startTimeOut = 20;
85         # 1 sec as infinity must be ok, but ...  
86         my $smallTimeOut = 10;
87         # Nbr of 1/10 of second we wait an answer of "?"
88         my $workTimeOut = 200;
90         myMakeFifo($outFifo);
92         # unlock the "?", wait $startTimeOut sec so that the "?" have the time
93         # to go in its communication loop (useful only when we
94         # start the "?")
95         $done = 0;
96         $i=0;
98         while(!$done) {
99                 if (! -p $lockFifo) {
100                         if ($i == $startTimeOut) {
101                                 unlink($outFifo);
102                                 die "com: No lock Fifo $lockFifo for $name communication\n";
103                         }
104                         $i++;
105                         sleep(1);
106                 } else {
107                         eval {
108                                 local $SIG{ALRM} = sub { die "Timeout" };
109                                 alarm("$smallTimeOut");
110                                 # block unless "?" is ready to write on $lockFifo
111                                 open(LOCK,"$lockFifo") || die "cannot";
112                                 close(LOCK);
113                         };
114                         if ($@ =~ /^Timeout/) {
115                                 print STDERR "com: $name does not want to communicate\n";
116                                 unlink($outFifo);
117                                 exit(0);
118                         }
119                         if ($@ =~ /^cannot/) {
120                                 print STDERR "com: cannot open fifo $outFifo\n";
121                                 unlink($outFifo);
122                                 exit(0);
123                         }
124                         $done = 1;
125                 }
126         }
128         # send the message to "?"
129         eval {
130                 local $SIG{ALRM} = sub { die "Timeout" };
131                 alarm("$smallTimeOut");
132                 # this line block until the "?" read the message
133                 open(OUT,">$outFifo") || die "cannot";
134                 alarm(0);
135                 print OUT $message."\n";
136                 close(OUT);
137         };
138         if ($@ =~ /^Timeout/) {
139                 print STDERR "com: $name does not want to read the message\n";
140                 unlink($outFifo);
141                 exit(0);
142         }
143         if ($@ =~ /^cannot/) {
144                 print STDERR "com: cannot write on fifo $outFifo\n";
145                 unlink($outFifo);
146                 exit(0);
147         }
148         unlink($outFifo);
150         exit(0) unless ($lockAndGet);
152         $done = 0;
153         $i = 0;
155         while(!$done) {
156                 if (-p $inFifo) {
157                         $answer[0]="";
159                         eval {
160                                 local $SIG{ALRM} = sub { die "Timeout" };
161                                 alarm("$smallTimeOut");
162                                 # block unless "?" is ready to write on $inFifo
163                                 open(IN,"$inFifo") || die "cannot";
164                                 alarm(0);
165                         };
166                         if ($@ =~ /Timeout/) {
167                                 print STDERR "com: $name does not answer!\n";
168                                 unlink($outFifo);
169                                 #unlink($lockFifo);
170                                 exit(0);
171                         }
172                         if ($@ =~ /cannot/) {
173                                 print STDERR "com: cannot read fifo $inFifo\n";
174                                 exit(0);
175                         }
177                         @answer = (<IN>);
178                         chomp($answer[0]);
179                         if ($answer[0] eq "ok") {
180                                 $l=1;
181                                 open(BUF,">$bufFile") if ($line != 0); 
182                                 while(defined $answer[$l]) {
183                                         print $answer[$l] if ($line == $l || $line == 0); 
184                                         print BUF $answer[$l] if ($line != 0);
185                                         $l++;
186                                 }
187                                 close(BUF) if ($line != 0);
188                                 $done=1;
189                         }
190                         if ($answer[0] eq "error") {
191                                 alarm(0);
192                                 print STDERR "com: An error happen in $name\n";
193                                 $done = 1;
194                         }
195                         close(IN);
196                 }
197                 # 
198                 if ($i == $workTimeOut) {
199                         print STDERR "com: $name does not answer the message!\n";
200                         $done = 1;
201                 }
202                 if (!$done) {
203                   select(undef,undef,undef,0.1);
204                   $i++;
205           }
206         }
208 #-----------------------------------------------------------------------------
210 # make a fifo
212 # ----------------------------------------------------------------------------
214 sub myMakeFifo {
215         my ($fifo) = @_;
216         my $ok=0;
217         my $i=0;
219         # not portable: mknod '$fifo' p
220         while(!$ok && $i < $mkFifoTimeOut) {
221                 if (system("mkfifo '$fifo' 2>/dev/null") == 0) {
222                         $ok = 1;
223                 }
224                 if (!$ok) {
225                         select(undef,undef,undef,0.1);
226                         $i++;
227                 }
228         }
229         if (!$ok) {
230                 print STDERR "fvwm-themes[com]: fail to create fifo $fifo\n";
231                 print STDERR "    Can you send a bug report to ".
232                   "fvwm-themes-devel\@lists.sourceforge.net";
233         }
235 #-----------------------------------------------------------------------------
237 # The standard functions
239 # ----------------------------------------------------------------------------
241 sub showHelp {
242         print "The fvwm-themes communicator utility.\n";
243         print "Usage: $scriptName [OPTIONS]\n";
244         print "Options:\n";
245         print "\t--help             show this help and exit\n";
246         print "\t--version          show the version and exit\n";
247         print "\t--name name        the name of the communication\n"; 
248         print "\t--message message  a one line message to be sent\n";
249         print "\t--lock-and-get     wait for an answer of the message\n";
250         print "\t--line n           concern the nth line of the buffer or answer\n";
251         print "\t--get-buffer       Out put the buffer file\n";
252         print "\t--buffer-name name alternative buffer file name\n";
253         print "\t--clear-buffer     remove the buffer file\n";
254         exit 0;
257 sub showVersion {
258         print "$version\n";
259         exit 0;
262 sub wrongUsage {
263         print STDERR "Try '$scriptName --help' for more information.\n";
264         exit -1;
267 # ----------------------------------------------------------------------------
269 =head1 NAME
271 fvwm-themes-com - fvwm-themes communication center
273 =head1 SYNOPSIS
275 B<fvwm-themes-com>
276 [ B<--help>]
277 [ B<--version>]
278 [ B<--name> name ]
279 [ B<--message> message ]
280 [ B<--lock-and-get> ]
281 [ B<--get-buffer> ]
282 [ B<--clear-buffer> ]
283 [ B<--buffer-name> name ]
284 [ B<--line> lineNbr]
286 =head1 DESCRIPTION
288 This script is not a user script. It is used by Fvwm-Themes for communication
289 between some FvwmScript scripts and some other programs. Basically, you want
290 to start a programs in the background which support the fvwm-themes-com 
291 communication protocol (e.g., fvwm-themes-menuapp and fvwm-themes-config
292 with the com-mode option can be used as generic examples), 
293 then you can use fvwm-themes-com to ask 
294 questions or to give instructions to the background program. The answer are 
295 displayed by fvwm-themes-com in the standard out put and can be used by a 
296 FvwmScript script via the GetoutPut instruction. 
297 The advantage of using this method is that the background program
298 have to do its main job only once (e.g., parsing a lot of informations and
299 storing them in some variables) and a script can have very fast answer
300 from the background program via fvwm-themes-com.
302 =head1 OPTIONS
304 B<--help>    - show the help and exit
306 B<--version> - show the version and exit
308 B<--name> name - the name of the communication (e.g., if you start 
309 fvwm-themes-menuapp with --com-name pid option you must use menuapp-pid
310 as name to communicate with it). The pipe used for communication are
311 $FVWM_DATADIR/{.tmp-com-in-name,tmp-com-out-name,tmp-com-lock-name}.
312 The "buffer" file is $FVWM_USERDIR/.tmp-com-buffer-name
314 B<--message> - A one line message to be sent to the back program. 
316 B<--lock-and-get> - Wait (a certain "time out") for an answer of the message.
317 Then, the answer is displayed on STDOUT.
319 B<--line> n - n must be an integer n > 0. In the case of a lock and get
320 message, fvwm-themes-com will out put only the nth line of the answer of 
321 the back program on STDOUT and will copy the complete answer in a "buffer" 
322 file. If you use the get-buffer option the nth line of the buffer is out
323 put on STDOUT.   
325 B<--get-buffer> - Out put the buffer file on STDOUT.
327 B<--buffer-name> othername - Use an alternative name for the buffer 
328 file: $FVWM_USERDIR/.tmp-com-buffer-othername. This is usefull if
329 two programs use the same background program and both use the buffer.
331 B<--clear-buffer> - remove the buffer file.
333 =head1 USAGE
335 Here an example:
337 In the Script FvwmScript-Menus you first start the background program, here
338 fvwm-themes-menuapp, and you set some variables for an easy use of
339 fvwm-themes-com:
341   # found the FvwmScript pid
342   Set $CMD = {perl -e '$t=getppid; print $t . "\n"'}
343   Set $PID = (GetOutput $CMD 1 -1)
344   # Run fvwm-themes-menuapp until the end of the script
345   Do {Exec fvwm-themes-menuapp --com-mode --com-name=menuapp-}$PID{ &}
346   # to send fvwm-themes-com command
347   Set $SendMsgAndGet = {fvwm-themes-com --name menuapp-}$PID{ --lock-and-get --message=}
348   Set $SendMsg = {fvwm-themes-com --name menuapp-}$PID{  --message=}
349   Set $GetLine = {fvwm-themes-com --name menuapp-}$PID{  --get-buffer --line=}
351 Then in the Script you can ask fvwm-themes-menuapp for some informations:
353   # Get the menu list
354   Set $CMD = $SendMsgAndGet{"menu-items }$MENU{"}
355   Set $ItemsList = (GetOutput $CMD 1 -1)
356   ChangeTitle 11 $ItemsList
358 You can also just send an instruction to fvwm-themes-menuapp:
360   Set $CMD = $SendMsg{"exit"}
361   Do {Exec }$CMD
363 Of course your back program have to support the fvwm-themes-com
364 protocol. See fvwm-themes-menuapp and fvwm-themes-config for examples 
365 (com-mode option).
366 See also FvwmScript-Menus and FvwmScript-ThemesCenter.
368 =head1 AUTHORS
370 Olivier Chapuis <olivier.chapuis@free.fr>, 5 May 2000.
372 =head1 COPYING
374 The script is distributed by the same terms as fvwm itself.
375 See GNU General Public License for details.
377 =head1 BUGS
379 Report bugs to fvwm-themes-devel@lists.sourceforge.net
381 =cut
383 # ----------------------------------------------------------------------------