xref: /netbsd-src/external/bsd/ntp/dist/sntp/libopts/pgusage.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /*	$NetBSD: pgusage.c,v 1.1.1.1 2009/12/13 16:57:19 kardel Exp $	*/
2 
3 
4 /*
5  *  Id: da09fc943da953195b243b7697fdbf5127f5b6c2
6  * Time-stamp:      "2009-11-01 11:52:51 bkorb"
7  *
8  *   Automated Options Paged Usage module.
9  *
10  *  This routine will run run-on options through a pager so the
11  *  user may examine, print or edit them at their leisure.
12  *
13  *  This file is part of AutoOpts, a companion to AutoGen.
14  *  AutoOpts is free software.
15  *  AutoOpts is copyright (c) 1992-2009 by Bruce Korb - all rights reserved
16  *
17  *  AutoOpts is available under any one of two licenses.  The license
18  *  in use must be one of these two and the choice is under the control
19  *  of the user of the license.
20  *
21  *   The GNU Lesser General Public License, version 3 or later
22  *      See the files "COPYING.lgplv3" and "COPYING.gplv3"
23  *
24  *   The Modified Berkeley Software Distribution License
25  *      See the file "COPYING.mbsd"
26  *
27  *  These files have the following md5sums:
28  *
29  *  43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
30  *  06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
31  *  66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
32  */
33 
34 tePagerState pagerState = PAGER_STATE_INITIAL;
35 
36 /*=export_func  optionPagedUsage
37  * private:
38  *
39  * what:  Decipher a boolean value
40  * arg:   + tOptions* + pOpts    + program options descriptor +
41  * arg:   + tOptDesc* + pOptDesc + the descriptor for this arg +
42  *
43  * doc:
44  *  Run the usage output through a pager.
45  *  This is very handy if it is very long.
46  *  This is disabled on platforms without a working fork() function.
47 =*/
48 void
49 optionPagedUsage( tOptions* pOptions, tOptDesc* pOD )
50 {
51 #if ! defined(HAVE_WORKING_FORK)
52     if ((pOD->fOptState & OPTST_RESET) != 0)
53         return;
54 
55     (*pOptions->pUsageProc)( pOptions, EXIT_SUCCESS );
56 #else
57     static pid_t     my_pid;
58     char zPageUsage[ 1024 ];
59 
60     /*
61      *  IF we are being called after the usage proc is done
62      *     (and thus has called "exit(2)")
63      *  THEN invoke the pager to page through the usage file we created.
64      */
65     switch (pagerState) {
66     case PAGER_STATE_INITIAL:
67     {
68         if ((pOD->fOptState & OPTST_RESET) != 0)
69             return;
70 
71         my_pid  = getpid();
72 #ifdef HAVE_SNPRINTF
73         snprintf(zPageUsage, sizeof(zPageUsage), "/tmp/use.%lu", (tAoUL)my_pid);
74 #else
75         sprintf( zPageUsage, "/tmp/use.%lu", (tAoUL)my_pid );
76 #endif
77         unlink( zPageUsage );
78 
79         /*
80          *  Set usage output to this temporary file
81          */
82         option_usage_fp = fopen( zPageUsage, "w" FOPEN_BINARY_FLAG );
83         if (option_usage_fp == NULL)
84             _exit( EXIT_FAILURE );
85 
86         pagerState = PAGER_STATE_READY;
87 
88         /*
89          *  Set up so this routine gets called during the exit logic
90          */
91         atexit( (void(*)(void))optionPagedUsage );
92 
93         /*
94          *  The usage procedure will now put the usage information into
95          *  the temporary file we created above.
96          */
97         (*pOptions->pUsageProc)( pOptions, EXIT_SUCCESS );
98 
99         /* NOTREACHED */
100         _exit( EXIT_FAILURE );
101     }
102 
103     case PAGER_STATE_READY:
104     {
105         tSCC zPage[]  = "%1$s /tmp/use.%2$lu ; rm -f /tmp/use.%2$lu";
106         tCC* pzPager  = (tCC*)getenv( "PAGER" );
107 
108         /*
109          *  Use the "more(1)" program if "PAGER" has not been defined
110          */
111         if (pzPager == NULL)
112             pzPager = "more";
113 
114         /*
115          *  Page the file and remove it when done.
116          */
117 #ifdef HAVE_SNPRINTF
118         snprintf(zPageUsage, sizeof(zPageUsage), zPage, pzPager, (tAoUL)my_pid);
119 #else
120         sprintf( zPageUsage, zPage, pzPager, (tAoUL)my_pid );
121 #endif
122         fclose( stderr );
123         dup2( STDOUT_FILENO, STDERR_FILENO );
124 
125         (void)system( zPageUsage );
126     }
127 
128     case PAGER_STATE_CHILD:
129         /*
130          *  This is a child process used in creating shell script usage.
131          */
132         break;
133     }
134 #endif
135 }
136 
137 /*
138  * Local Variables:
139  * mode: C
140  * c-file-style: "stroustrup"
141  * indent-tabs-mode: nil
142  * End:
143  * end of autoopts/pgusage.c */
144