Files
Arquivotheca.SunOS-4.1.4/usr.lib/libsuntool/help/help.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

322 lines
8.8 KiB
C

#ifndef lint
#ifdef sccs
static char sccsid[] = "@(#)help.c 1.1 94/10/31 Copyright 1987 Sun Micro";
#endif
#endif
/*
* Copyright (c) 1987 by Sun Microsystems, Inc.
*/
#include <stdio.h>
#include <rpc/rpc.h>
#include <sunwindow/defaults.h>
#include <suntool/sunview.h>
#include <suntool/alert.h>
#include <netdb.h>
#include <suntool/help.h>
#include <sys/socket.h> /* for callrpc2() */
#include <sys/time.h> /* for callrpc2() */
#include <strings.h> /* for callrpc2() */
#define HELPNAMELENGTH 256
#define HELPTEXTLINES 32
static short help_image[] = {
#include <images/help.icon>
};
mpr_static(help_request_icon, 64, 64, 1, help_image);
static struct timeval timeout1 = { 5, 0 };
static struct timeval timeout2 = { 25, 0 };
static void help_request_default();
static void (*help_request_func)() = help_request_default;
static void help_more_default();
static void (*help_more_func)();
static void help_set_server();
static char help_server_name[HELPNAMELENGTH];
static int help_request_seq;
static void
help_request_failed(window, data, str, why, event)
Window window;
char *data, *str, *why;
Event *event;
{
char message[256];
if (data) {
sprintf(message, "%s for %s.", str, data);
} else {
sprintf(message, "%s.", str);
}
alert_prompt(NULL, event,
ALERT_POSITION, ALERT_SCREEN_CENTERED,
ALERT_MESSAGE_STRINGS, message, 0,
ALERT_BUTTON_YES, "OK", 0,
HELP_DATA, why,
0);
}
/*
* Default more help delivery function
*/
static void
help_more_default(client, data, event)
Window client;
char *data;
Event *event;
{
Help_request arg;
char command[HELPNAMELENGTH+2];
int ret, callrpc2();
arg.data = data;
if (event) {
arg.x = event_x(event);
arg.y = event_y(event);
}
arg.pid = getpid();
arg.seq = ++help_request_seq;
if (help_server_name[0] == '\0') {
/* Get server name from defaults database */
strncpy(help_server_name,
defaults_get_string("/Help/Server", HELPDEFAULTSERVER, 0),
HELPNAMELENGTH - 1);
}
if (callrpc2("localhost", HELPDEFAULTPROG, HELPVERS, HELPREQUEST,
xdr_help, &arg, xdr_void, NULL, &timeout1)) {
/* This fixes a bug where the user quits & restarts help servers */
/* between rpc calls. If this is the case, the second call should */
/* now go through: */
ret = callrpc2("localhost", HELPDEFAULTPROG, HELPVERS, HELPREQUEST,
xdr_help, &arg, xdr_void, NULL, &timeout2);
if (ret) {
/* Request failed, spawn help server */
if (alert_prompt(NULL, NULL,
ALERT_POSITION, ALERT_SCREEN_CENTERED,
ALERT_MESSAGE_STRINGS,
"A help server to display more help",
"was not found. There will be a short",
"delay while one is started.",
" ",
" ",
NULL,
ALERT_BUTTON_YES, "Continue",
ALERT_BUTTON_NO, "Cancel",
NULL)
== ALERT_YES) {
sprintf(command, "%s '%s' &", help_server_name, data);
system(command);
}
}
}
return;
}
/*
* Default request function
*/
static void
help_request_default(client_window, client_data, client_event)
Window client_window;
caddr_t client_data;
Event *client_event;
{
char *arg = help_get_arg(client_data),
*text = (arg ? help_get_text() : NULL),
buffer[HELPTEXTLINES][80],
*array[HELPTEXTLINES+1];
Event event;
int i, more_info = TRUE;
int use_doc = (arg ? *arg != '\0' : FALSE);
if (client_event) {
event = *client_event;
}
if (text) {
for (i = 0; text && i < HELPTEXTLINES; ++i, (text = help_get_text())) {
array[i] = (char *)strncpy(buffer[i], text, sizeof(buffer[i]) - 1);
if (buffer[i][strlen(buffer[i]) - 1] == '\n')
buffer[i][strlen(buffer[i]) - 1] = '\0';
}
array[i] = NULL;
more_info = (alert_prompt(NULL, &event,
HELP_DATA, "sunview:helpalert",
ALERT_IMAGE, &help_request_icon,
ALERT_POSITION, ALERT_SCREEN_CENTERED,
ALERT_NO_BEEPING, TRUE,
ALERT_MESSAGE_STRINGS_ARRAY_PTR, array,
ALERT_BUTTON_YES, "Done",
(use_doc ? ALERT_BUTTON_NO : 0), "More Help",
0)
== ALERT_NO);
} else if (text || (!text && !use_doc)) {
help_request_failed(client_window, client_data,
"No help is available", "sunview:helpnoinfo",
&event);
}
/* This sends a help request directly to the help */
/* server, with no intervening Spot Help message. */
if (use_doc && more_info) {
help_more(client_window, arg, &event);
}
}
/*
* Public interfaces
*/
void
help_request(client, data, event)
Window client;
caddr_t data;
Event *event;
{
if (help_request_func) {
help_request_func(client, data, event);
}
}
void
help_more(client, data, event)
Window client;
char *data;
Event *event;
{
if (! help_more_func) {
help_more_func = help_more_default;
}
(*help_more_func)(client, data, event);
}
void
help_set_request_func(func)
void (*func)();
{
help_request_func = func;
}
void
help_set_more_func(func)
void (*func)();
{
help_more_func = func;
}
/*
* callrpc(), with timeout parameter:
*/
static struct callrpc_private {
CLIENT *client;
int socket;
int oldprognum, oldversnum, valid;
char *oldhost;
} *callrpc_private;
callrpc2(host, prognum, versnum, procnum, inproc, in, outproc, out, tottimeout)
char *host;
xdrproc_t inproc, outproc;
char *in, *out;
struct timeval *tottimeout;
{
register struct callrpc_private *crp = callrpc_private;
struct sockaddr_in server_addr;
enum clnt_stat clnt_stat;
struct hostent *hp;
struct timeval timeout;
if (crp == 0) {
crp = (struct callrpc_private *)calloc(1, sizeof (*crp));
if (crp == 0)
return (0);
callrpc_private = crp;
}
if (crp->oldhost == NULL) {
crp->oldhost = malloc(256);
crp->oldhost[0] = 0;
crp->socket = RPC_ANYSOCK;
}
if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
&& strcmp(crp->oldhost, host) == 0) {
/* reuse old client */
} else {
crp->valid = 0;
(void)close(crp->socket);
crp->socket = RPC_ANYSOCK;
if (crp->client) {
clnt_destroy(crp->client);
crp->client = NULL;
}
if ((hp = gethostbyname(host)) == NULL)
return ((int) RPC_UNKNOWNHOST);
timeout.tv_usec = 0;
timeout.tv_sec = 5;
bcopy(hp->h_addr, (char *)&server_addr.sin_addr, hp->h_length);
server_addr.sin_family = AF_INET;
server_addr.sin_port = 0;
if ((crp->client = clntudp_create(&server_addr, (u_long)prognum,
(u_long)versnum, timeout, &crp->socket)) == NULL)
return ((int) rpc_createerr.cf_stat);
crp->valid = 1;
crp->oldprognum = prognum;
crp->oldversnum = versnum;
(void) strcpy(crp->oldhost, host);
}
clnt_stat = clnt_call(crp->client, procnum, inproc, in,
outproc, out, *tottimeout);
/*
* if call failed, empty cache
*/
if (clnt_stat != RPC_SUCCESS)
crp->valid = 0;
return ((int) clnt_stat);
}