1 /*
2 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /*
7 * Copyright 1987, 1988 by MIT Student Information Processing Board
8 *
9 * For copyright information, see copyright.h.
10 */
11 #include "copyright.h"
12 #include "ss_internal.h"
13 #include <libintl.h>
14 #include <signal.h>
15 #include <setjmp.h>
16 #include <sys/wait.h>
17
18 #ifdef lint /* "lint returns a value which is sometimes ignored" */
19 #define DONT_USE(x) x=x;
20 #else /* !lint */
21 #define DONT_USE(x) ;
22 #endif /* lint */
23
24 extern int ss_pager_create();
25
26 static char const twentyfive_spaces[26] =
27 " ";
28 static char const NL[2] = "\n";
29
30 void
ss_list_requests(argc,argv,sci_idx,info_ptr)31 ss_list_requests(argc, argv, sci_idx, info_ptr)
32 int argc;
33 const char * const *argv;
34 int sci_idx;
35 #ifdef __STDC__
36 void *info_ptr;
37 #else
38 char *info_ptr;
39 #endif
40 {
41 register ss_request_entry *entry;
42 register char const * const *name;
43 register int spacing;
44 register ss_request_table **table;
45
46 char buffer[BUFSIZ];
47 FILE *output;
48 int fd;
49 #ifdef POSIX_SIGNALS
50 struct sigaction nsig, osig;
51 sigset_t nmask, omask;
52 #else
53 int mask;
54 RETSIGTYPE (*func)();
55 #endif
56 #ifndef WAIT_USES_INT
57 union wait waitb;
58 #else
59 int waitb;
60 #endif
61
62 DONT_USE(argc);
63 DONT_USE(argv);
64
65 #ifdef POSIX_SIGNALS
66 sigemptyset(&nmask);
67 sigaddset(&nmask, SIGINT);
68 sigprocmask(SIG_BLOCK, &nmask, &omask);
69
70 nsig.sa_handler = SIG_IGN;
71 sigemptyset(&nsig.sa_mask);
72 nsig.sa_flags = 0;
73 sigaction(SIGINT, &nsig, &osig);
74 #else
75 mask = sigblock(sigmask(SIGINT));
76 func = signal(SIGINT, SIG_IGN);
77 #endif
78
79 fd = ss_pager_create();
80 output = fdopen(fd, "w");
81
82 #ifdef POSIX_SIGNALS
83 sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
84 #else
85 sigsetmask(mask);
86 #endif
87
88 fprintf (output, dgettext(TEXT_DOMAIN, "Available %s requests:\n\n"),
89 ss_info (sci_idx) -> subsystem_name);
90
91 for (table = ss_info(sci_idx)->rqt_tables; *table; table++) {
92 entry = (*table)->requests;
93 for (; entry->command_names; entry++) {
94 spacing = -2;
95 buffer[0] = '\0';
96 if (entry->flags & SS_OPT_DONT_LIST)
97 continue;
98 buffer[sizeof(buffer) - 1] = '\0';
99 for (name = entry->command_names; *name; name++) {
100 register int len = strlen(*name);
101 strncat(buffer, *name, sizeof(buffer) - 1 - strlen(buffer));
102 spacing += len + 2;
103 if (name[1]) {
104 strncat(buffer, ", ", sizeof(buffer) - 1 - strlen(buffer));
105 }
106 }
107 if (spacing > 23) {
108 strncat(buffer, NL, sizeof(buffer) - 1 - strlen(buffer));
109 fputs(buffer, output);
110 spacing = 0;
111 buffer[0] = '\0';
112 }
113 strncat(buffer, twentyfive_spaces, strlen(twentyfive_spaces) - spacing);
114
115 /*
116 * Due to libss not knowing what TEXT_DOMAIN
117 * the calling application is using for its info_string
118 * messages, we know require the callers (ktutil,kadmin)
119 * to L10N the messages before calling libss.
120 */
121 strncat(buffer, entry->info_string, sizeof(buffer) -1 - strlen(buffer));
122 strncat(buffer, NL, sizeof(buffer) - 1 - strlen(buffer));
123 fputs(buffer, output);
124 }
125 }
126 fclose(output);
127 #ifndef NO_FORK
128 wait(&waitb);
129 #endif
130 #ifdef POSIX_SIGNALS
131 sigaction(SIGINT, &osig, (struct sigaction *)0);
132 #else
133 (void) signal(SIGINT, func);
134 #endif
135 }
136