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