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