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