xref: /freebsd/contrib/ntp/sntp/libopts/pgusage.c (revision b1f9167f94059fd55c630891d359bcff987bd7eb)
1 
2 /*
3  *  $Id: pgusage.c,v 4.12 2007/04/28 22:19:23 bkorb Exp $
4  * Time-stamp:      "2006-07-16 08:13:26 bkorb"
5  *
6  *   Automated Options Paged Usage module.
7  *
8  *  This routine will run run-on options through a pager so the
9  *  user may examine, print or edit them at their leisure.
10  */
11 
12 /*
13  *  Automated Options copyright 1992-2007 Bruce Korb
14  *
15  *  Automated Options is free software.
16  *  You may redistribute it and/or modify it under the terms of the
17  *  GNU General Public License, as published by the Free Software
18  *  Foundation; either version 2, or (at your option) any later version.
19  *
20  *  Automated Options is distributed in the hope that it will be useful,
21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  *  GNU General Public License for more details.
24  *
25  *  You should have received a copy of the GNU General Public License
26  *  along with Automated Options.  See the file "COPYING".  If not,
27  *  write to:  The Free Software Foundation, Inc.,
28  *             51 Franklin Street, Fifth Floor,
29  *             Boston, MA  02110-1301, USA.
30  *
31  * As a special exception, Bruce Korb gives permission for additional
32  * uses of the text contained in his release of AutoOpts.
33  *
34  * The exception is that, if you link the AutoOpts library with other
35  * files to produce an executable, this does not by itself cause the
36  * resulting executable to be covered by the GNU General Public License.
37  * Your use of that executable is in no way restricted on account of
38  * linking the AutoOpts library code into it.
39  *
40  * This exception does not however invalidate any other reasons why
41  * the executable file might be covered by the GNU General Public License.
42  *
43  * This exception applies only to the code released by Bruce Korb under
44  * the name AutoOpts.  If you copy code from other sources under the
45  * General Public License into a copy of AutoOpts, as the General Public
46  * License permits, the exception does not apply to the code that you add
47  * in this way.  To avoid misleading anyone as to the status of such
48  * modified files, you must delete this exception notice from them.
49  *
50  * If you write modifications of your own for AutoOpts, it is your choice
51  * whether to permit this exception to apply to your modifications.
52  * If you do not wish that, delete this exception notice.
53  */
54 
55 tePagerState pagerState = PAGER_STATE_INITIAL;
56 
57 /*=export_func  optionPagedUsage
58  * private:
59  *
60  * what:  Decipher a boolean value
61  * arg:   + tOptions* + pOpts    + program options descriptor +
62  * arg:   + tOptDesc* + pOptDesc + the descriptor for this arg +
63  *
64  * doc:
65  *  Run the usage output through a pager.
66  *  This is very handy if it is very long.
67 =*/
68 void
69 optionPagedUsage( tOptions* pOptions, tOptDesc* pOD )
70 {
71 #if defined(__windows__) && !defined(__CYGWIN__)
72     (*pOptions->pUsageProc)( pOptions, EXIT_SUCCESS );
73 #else
74     static pid_t     my_pid;
75     char zPageUsage[ 1024 ];
76 
77     /*
78      *  IF we are being called after the usage proc is done
79      *     (and thus has called "exit(2)")
80      *  THEN invoke the pager to page through the usage file we created.
81      */
82     switch (pagerState) {
83     case PAGER_STATE_INITIAL:
84     {
85         my_pid  = getpid();
86 #ifdef HAVE_SNPRINTF
87         snprintf(zPageUsage, sizeof(zPageUsage), "/tmp/use.%lu", (tAoUL)my_pid);
88 #else
89         sprintf( zPageUsage, "/tmp/use.%lu", (tAoUL)my_pid );
90 #endif
91         unlink( zPageUsage );
92 
93         /*
94          *  Set usage output to this temporary file
95          */
96         option_usage_fp = fopen( zPageUsage, "w" FOPEN_BINARY_FLAG );
97         if (option_usage_fp == NULL)
98             _exit( EXIT_FAILURE );
99 
100         pagerState = PAGER_STATE_READY;
101 
102         /*
103          *  Set up so this routine gets called during the exit logic
104          */
105         atexit( (void(*)(void))optionPagedUsage );
106 
107         /*
108          *  The usage procedure will now put the usage information into
109          *  the temporary file we created above.
110          */
111         (*pOptions->pUsageProc)( pOptions, EXIT_SUCCESS );
112 
113         /*NOTREACHED*/
114         _exit( EXIT_FAILURE );
115     }
116 
117     case PAGER_STATE_READY:
118     {
119         tSCC zPage[]  = "%1$s /tmp/use.%2$lu ; rm -f /tmp/use.%2$lu";
120         tCC* pzPager  = (tCC*)getenv( "PAGER" );
121 
122         /*
123          *  Use the "more(1)" program if "PAGER" has not been defined
124          */
125         if (pzPager == NULL)
126             pzPager = "more";
127 
128         /*
129          *  Page the file and remove it when done.
130          */
131 #ifdef HAVE_SNPRINTF
132         snprintf(zPageUsage, sizeof(zPageUsage), zPage, pzPager, (tAoUL)my_pid);
133 #else
134         sprintf( zPageUsage, zPage, pzPager, (tAoUL)my_pid );
135 #endif
136         fclose( stderr );
137         dup2( STDOUT_FILENO, STDERR_FILENO );
138 
139         (void)system( zPageUsage );
140     }
141 
142     case PAGER_STATE_CHILD:
143         /*
144          *  This is a child process used in creating shell script usage.
145          */
146         break;
147     }
148 #endif
149 }
150 
151 /*
152  * Local Variables:
153  * mode: C
154  * c-file-style: "stroustrup"
155  * indent-tabs-mode: nil
156  * End:
157  * end of autoopts/pgusage.c */
158