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 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