void ss_add_request_table(int sci_idx, ssrt *rqtbl_ptr, int position, int *code_ptr) { register ss_data *info; register int i, size; ssrt **t; info = ss_info(sci_idx); for (size=0; info->rqt_tables[size] != (ssrt *)NULL; size++) ; /* size == C subscript of NULL == #elements */ size += 2; /* new element, and NULL */ t = (ssrt **)realloc(info->rqt_tables, (unsigned)size*sizeof(ssrt *)); if (t == (ssrt **)NULL) { *code_ptr = errno; return; } info->rqt_tables = t; if (position > size - 2) position = size - 2; if (size > 1) for (i = size - 2; i >= position; i--) info->rqt_tables[i+1] = info->rqt_tables[i]; info->rqt_tables[position] = rqtbl_ptr; info->rqt_tables[size-1] = (ssrt *)NULL; *code_ptr = 0; }
void ss_get_readline(int sci_idx) { #ifdef HAVE_DLOPEN void *handle = NULL; ss_data *info = ss_info(sci_idx); const char **t, *libpath = 0; char *tmp, *cp, *next; char **(**completion_func)(const char *, int, int); if (info->readline_handle) return; libpath = ss_safe_getenv("SS_READLINE_PATH"); if (!libpath) libpath = DEFAULT_LIBPATH; if (*libpath == 0 || !strcmp(libpath, "none")) return; tmp = malloc(strlen(libpath)+1); if (!tmp) return; strcpy(tmp, libpath); for (cp = tmp; cp; cp = next) { next = strchr(cp, ':'); if (next) *next++ = 0; if (*cp == 0) continue; if ((handle = dlopen(cp, RTLD_NOW))) { /* printf("Using %s for readline library\n", cp); */ break; } } free(tmp); if (!handle) return; info->readline_handle = handle; info->readline = (char *(*)(const char *)) dlsym(handle, "readline"); info->add_history = (void (*)(const char *)) dlsym(handle, "add_history"); info->redisplay = (void (*)(void)) dlsym(handle, "rl_forced_update_display"); info->rl_completion_matches = (char **(*)(const char *, char *(*)(const char *, int))) dlsym(handle, "rl_completion_matches"); if ((t = dlsym(handle, "rl_readline_name")) != NULL) *t = info->subsystem_name; if ((completion_func = dlsym(handle, "rl_attempted_completion_function")) != NULL) *completion_func = ss_rl_completion; info->readline_shutdown = ss_release_readline; #endif }
void ss_delete_request_table(int sci_idx, ssrt *rqtbl_ptr, int *code_ptr) { register ss_data *info; register ssrt **rt1, **rt2; *code_ptr = SS_ET_TABLE_NOT_FOUND; info = ss_info(sci_idx); rt1 = info->rqt_tables; for (rt2 = rt1; *rt1; rt1++) { if (*rt1 != rqtbl_ptr) { *rt2++ = *rt1; *code_ptr = 0; } } *rt2 = (ssrt *)NULL; return; }
void ss_delete_invocation(int sci_idx) { register ss_data *t; int ignored_code; t = ss_info(sci_idx); free(t->prompt); free(t->rqt_tables); while(t->info_dirs[0] != (char *)NULL) ss_delete_info_dir(sci_idx, t->info_dirs[0], &ignored_code); free(t->info_dirs); #if defined(HAVE_DLOPEN) && defined(SHARED_ELF_LIB) if (t->readline_shutdown) (*t->readline_shutdown)(t); #endif free(t); }
char *ss_name(int sci_idx) { register char *ret_val; register ss_data *infop; infop = ss_info(sci_idx); if (infop->current_request == (char const *)NULL) { ret_val = malloc((unsigned) (strlen(infop->subsystem_name)+1) * sizeof(char)); if (ret_val == (char *)NULL) return((char *)NULL); strcpy(ret_val, infop->subsystem_name); return(ret_val); } else { register char *cp; register char const *cp1; ret_val = malloc((unsigned)sizeof(char) * (strlen(infop->subsystem_name)+ strlen(infop->current_request)+ 4)); cp = ret_val; cp1 = infop->subsystem_name; while (*cp1) *cp++ = *cp1++; *cp++ = ' '; *cp++ = '('; cp1 = infop->current_request; while (*cp1) *cp++ = *cp1++; *cp++ = ')'; *cp = '\0'; return(ret_val); } }
int ss_listen (int sci_idx) { char *cp; ss_data *info; sigret_t (*sig_int)(int), (*old_sig_cont)(int); char input[BUFSIZ]; sigset_t omask, igmask; int code; jmp_buf old_jmpb; ss_data *old_info = current_info; char *line; current_info = info = ss_info(sci_idx); sig_cont = (sigret_t (*)(int)) 0; info->abort = 0; sigemptyset(&igmask); sigaddset(&igmask, SIGINT); sigprocmask(SIG_BLOCK, &igmask, &omask); memcpy(old_jmpb, listen_jmpb, sizeof(jmp_buf)); sig_int = signal(SIGINT, listen_int_handler); setjmp(listen_jmpb); sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0); while(!info->abort) { old_sig_cont = sig_cont; sig_cont = signal(SIGCONT, print_prompt); if (sig_cont == print_prompt) sig_cont = old_sig_cont; if (info->readline) { line = (*info->readline)(current_info->prompt); } else { print_prompt(0); if (fgets(input, BUFSIZ, stdin) == input) line = input; else line = NULL; input[BUFSIZ-1] = 0; } if (line == NULL) { code = SS_ET_EOF; (void) signal(SIGCONT, sig_cont); goto egress; } cp = strchr(line, '\n'); if (cp) { *cp = '\0'; if (cp == line) continue; } (void) signal(SIGCONT, sig_cont); if (info->add_history) (*info->add_history)(line); code = ss_execute_line (sci_idx, line); if (code == SS_ET_COMMAND_NOT_FOUND) { register char *c = line; while (*c == ' ' || *c == '\t') c++; cp = strchr (c, ' '); if (cp) *cp = '\0'; cp = strchr (c, '\t'); if (cp) *cp = '\0'; ss_error (sci_idx, 0, "Unknown request \"%s\". Type \"?\" for a request list.", c); } if (info->readline) free(line); } code = 0; egress: (void) signal(SIGINT, sig_int); memcpy(listen_jmpb, old_jmpb, sizeof(jmp_buf)); current_info = old_info; return code; }
void ss_abort_subsystem(int sci_idx, int code) { ss_info(sci_idx)->abort = 1; ss_info(sci_idx)->exit_status = code; }
int ss_listen (int sci_idx) { char *cp; ss_data *info; sigret_t (*sig_int)(int), (*sig_cont)(int), (*old_sig_cont)(int); char input[BUFSIZ]; char buffer[BUFSIZ]; char *end = buffer; #ifdef POSIX_SIGNALS sigset_t omask, igmask; #else int mask; #endif int code; jmp_buf old_jmpb; ss_data *old_info = current_info; current_info = info = ss_info(sci_idx); sig_cont = (sigret_t (*)(int)) 0; info->abort = 0; #ifdef POSIX_SIGNALS sigemptyset(&igmask); sigaddset(&igmask, SIGINT); sigprocmask(SIG_BLOCK, &igmask, &omask); #else mask = sigblock(sigmask(SIGINT)); #endif memcpy(old_jmpb, listen_jmpb, sizeof(jmp_buf)); sig_int = signal(SIGINT, listen_int_handler); setjmp(listen_jmpb); #ifdef POSIX_SIGNALS sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0); #else (void) sigsetmask(mask); #endif while(!info->abort) { print_prompt(0); *end = '\0'; old_sig_cont = sig_cont; sig_cont = signal(SIGCONT, print_prompt); if (sig_cont == print_prompt) sig_cont = old_sig_cont; if (fgets(input, BUFSIZ, stdin) != input) { code = SS_ET_EOF; goto egress; } cp = strchr(input, '\n'); if (cp) { *cp = '\0'; if (cp == input) continue; } (void) signal(SIGCONT, sig_cont); for (end = input; *end; end++) ; code = ss_execute_line (sci_idx, input); if (code == SS_ET_COMMAND_NOT_FOUND) { register char *c = input; while (*c == ' ' || *c == '\t') c++; cp = strchr (c, ' '); if (cp) *cp = '\0'; cp = strchr (c, '\t'); if (cp) *cp = '\0'; ss_error (sci_idx, 0, "Unknown request \"%s\". Type \"?\" for a request list.", c); } } code = 0; egress: (void) signal(SIGINT, sig_int); memcpy(listen_jmpb, old_jmpb, sizeof(jmp_buf)); current_info = old_info; return code; }
char *ss_get_prompt(int sci_idx) { return(ss_info(sci_idx)->prompt); }
void ss_set_prompt(int sci_idx, char *new_prompt) { ss_info(sci_idx)->prompt = new_prompt; }
sigset_t omask, igmask; sigret_t (*func)(int); #ifndef NO_FORK int waitb; #endif sigemptyset(&igmask); sigaddset(&igmask, SIGINT); sigprocmask(SIG_BLOCK, &igmask, &omask); func = signal(SIGINT, SIG_IGN); fd = ss_pager_create(); output = fdopen(fd, "w"); sigprocmask(SIG_SETMASK, &omask, (sigset_t *) 0); fprintf (output, "Available %s requests:\n\n", ss_info (sci_idx) -> subsystem_name); for (table = ss_info(sci_idx)->rqt_tables; *table; table++) { entry = (*table)->requests; for (; entry->command_names; entry++) { spacing = -2; buffer[0] = '\0'; if (entry->flags & SS_OPT_DONT_LIST) continue; for (name = entry->command_names; *name; name++) { int len = strlen(*name); strncat(buffer, *name, len); spacing += len + 2; if (name[1]) { strcat(buffer, ", "); }