SUMMARY; answerbook

nesrin_ozus@karmaint.com.tr
Thu, 04 Dec 1997 16:29:59 +0200

Hi,

I will give the answers below. I am planning to upgrade Solaris 2.6. So I
will wait this one. But Samir Arora send a program to be able to
read answer books from exceed. I want to try this one also on one of
servers but I did not do yet. Thanks to all.

Thank you very much for all your answers and anyone whos' reply I have not
yet received

gautam@bwc.org
Matthew.Stier@tddny.fujitsu.com (Matthew Lee Stier)
rsk@itw.com (Rich Kulawiec)
arunde@mms.com (Aline Runde)
sarora@eldec.com (Samir Arora)
admin@lovely.ucsd.edu (Matt ...)
fischjns@kat.ina.de (Jens Fischer)
itc1@scigen.co.uk (Ian ...)

My question was;
"Hi,
I know that this is not very critical problem but I need help. I searched
through FAQ and summaries but I could not find any solution.
We are using SUN Sparc 2 servers with Solaris 2.5.1
And we are using Exceed 6.0 for X terminal emulation software on our NT Ws
4.0 PCs. It works. But I could not use answerbook of server from my PC
when
I connect via exceed. I know that this problem related with exceed and it
does not support adobe script files.
Is there any shareware software that can be used on NT to be able to read
answerbooks. I can read the answerbook for System Adm. from console of the
server. We have answerbook for workshop C++ compiler and debugger but
development team could not read this from their PCs.
Maybe You use some tools to reach the answerbooks.
I will summarize.
Thanks in advance.
Nesrin OZUS
nesrin_ozus@karmaint.com"

And Answers:

1- Upgrade to Solaris 2.6. The answerbook is served via WEB and you can
read it via Netscpape or other web browser.

2- The problem is that; although the Answerbook Navigator is pure X11, the
Viewer depends upon NeWS or Display PostScript, which Exceed does not
support.

There was a workaround that used GhostScript to generate the pages as X11
Bitmaps. The only short coming I'm aware of, is that the on page hotlinks
are
lost.

Search the web, for the keys Answerbook and Ghostscript.

3- FYI, check Sun webpage: http://docs.sun.com/ab2

4- Hi Nesrin,
Below is attached summary of how to read the answerbook Via Exceed.
Hope that helps
Regards
Samir

The answer(s):
Answerbook requires a PostScript viewer to function and normally uses
(under 4.1.x) the NeWs software to display the pages. eXceed does not
have PostScript capability built in.
As for workarounds. Although, just about everyone agreed on the cause, the
solutions ranged from "It will not work with eXceed" to simply "Install
Ghostscript." What appears to be the ultimate solution to the problem was
sent
to me by several people in the form of "a shar file for the docviewer mods
to allow reading Answer Book on non-DPS capable systems using ghostview."
This was apparently posted to the list back in April by Chris Philips (why
is it that you can never remember these things when you need them?? ). You
will also have to install ghostscript for it to work.
From: sun-managers-relay
To: sun-managers
Subject: SUMMARY II : Answerbook under X11R6
Date: Friday, April 12, 1996 1:33PM
Yeahh, thanks to all answer my question but special thanks
to Chriss Phillips.
Here go your response.
>From chris@otter.cs.yorku.ca Fri Apr 12 12:56 CST 1996
The following is a shar file for the docviewer mods to allow
reading Answer Book on non-DPS capable systems using ghostview:
#!/bin/sh
# This is a shell archive (shar 3.21)
# made 09/22/1995 18:32 UTC by chris@otter
# Source directory /nfs/loon/disk4/pd/sys_2/chris/Active/Solaris/docviewer
#
# existing files WILL be overwritten
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 10911 -rw-r----- docviewer.c
# 633 -rwxr-xr-x answerbook_setup
#
if touch 2>&1 | fgrep '[-amc]' > /dev/null
then TOUCH=touch
else TOUCH=true
fi
# ============= docviewer.c ==============
echo "x - extracting docviewer.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > docviewer.c &&
X/*
X * fake docviewer for X11R5
X * Charles Hedrick, hedrick@cs.rutgers.edu
X */
X
X
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/extensions/multibuf.h>
X#include <X11/Xos.h>
X#include <stdio.h>
X#include <string.h>
X#include <ndbm.h>
X#include <unistd.h>
X
Xint use_DPS = 0;
X/*
X * parse strings that have attr=value
X * start is the string to search
X * attr is "attr="
X * breaks is a string with all characters that terminate a value
X * mallocs the result, so make sure to free it.
X * return NULL if not found
X */
X
Xchar *getvalue(start, attr, breaks)
X char *start, *attr, *breaks;
X{
X char *result, *end, *retval;
X
X result = strstr(start, attr);
X if (! result)
X return NULL;
X
X result += strlen(attr);
X
X end = strpbrk (result, breaks);
X if (! end)
X return NULL;
X
X retval = (char *)malloc( end - result + 1);
X if (! retval) {
X fprintf (stderr, "malloc failed\n");
X exit(1);
X }
X
X strncpy(retval, result, end - result);
X retval[end-result] = 0;
X return retval;
X}
X
Xchar *ProgramName;
X
X
Xmain (argc, argv)
X int argc;
X char **argv;
X{
X char *docspec = NULL;
X char *catspec = NULL, *thiscat;
X char *bs, *bk, *dc, *id, *tocpath, *pspath, *psfile, *pspage;
X char buffer[512], buffer2[512], *cp, *cp2;
X int ch;
X FILE *catfile, *recfile;
X int i, maxfd; char **a;
X DBM *db;
X struct keyst {
X int count1;
X int count2;
X char stkey[128];
X } keyst;
X datum key, fetch;
X
X#ifdef DEBUG
X i = argc;
X a = argv;
X while (i > 0) {
X printf("|%s| ", a[0]);
X i--;
X a++;
X }
X printf("\n");
X#endif
X
XProgramName = argv[0];
X
X /*
X * call the real thing is we are runninw NeWS
X */
X
X{
X/*
X * Adobe-DPS-Extension
X * DPSExtension
X *
X */
X Display *dpy; /* X connection */
X char *displayname = NULL; /* server to contact */
X int n = 0;
X char **extlist;
X
X dpy = XOpenDisplay (displayname);
X
X if (!dpy) {
X fprintf (stderr, "%s: unable to open display \"%s\".\n",
X ProgramName, XDisplayName (displayname));
X exit (1);
X }
X
X extlist = XListExtensions (dpy, &n);
X if (extlist) {
X register int i;
X
X for (i = 0; i < n; i++) {
X if ( (strcmp (extlist[i] , "Adobe-DPS-Extension" )) == 0 ) {
X fprintf (stderr, "%s: Display has extension: %s.\n",
X ProgramName, extlist[i] );
X use_DPS = 1;
X break;
X }
X }
X XFreeExtensionList (extlist);
X }
X XCloseDisplay (dpy);
X}
X#ifdef NOTDEF
X if (cp = (char *)getenv("hasnews")) {
X if (strcmp(cp, "yes") == 0) {
X(void) fprintf(stderr, "execvp docviewer.REAL\n");
X execvp("docviewer.REAL", argv);
X(void) fprintf(stderr, "Nope, execvp docviewer\n");
X execvp("docviewer", argv);
X(void) fprintf(stderr, "Nope, bailing out\n");
X exit(99);
X }
X }
X#endif
X if ( use_DPS ) {
X(void) fprintf(stderr, "execvp docviewer.REAL\n");
X execvp("/usr/openwin/bin/docviewer.REAL", argv);
X(void) fprintf(stderr, "Nope, execvp docviewer\n");
X execvp("/usr/openwin/bin/docviewer", argv);
X(void) fprintf(stderr, "Nope, bailing out\n");
X exit(99);
X }
X
X(void) fprintf(stderr, "Using ghostview\n");
X
X /*
X * process only -d and -c
X * arguments look like
X * |docviewer| |-Wp| |441| |0| |-p| |C.i5guO X 128.6.26.11 0| |-d|
X |<bs=SUNWab_2_6;bk=SUNDIAG;dc=1034>| |-l| |C| |-c|
X
|/rutgers/AnswerBook/ab_cardcatalog:/rutgers/AnswerBook/Solaris_2.2_AB/ab_c
a
rdc
catalog|
X * docspec to the -d argument. This specifies the document and place
X * within the document
X * catspec to the -c argument. This is a list of card catalogs to
X * search
X */
X
X while (argc > 1) {
X if (strcmp(argv[1], "-Wp") == 0) {argv += 3; argc -= 3;}
X else if (strcmp(argv[1], "-p") == 0) {argv += 2; argc -= 2;}
X else if (strcmp(argv[1], "-d") == 0)
X {docspec = argv[2]; argv += 2; argc -= 2;}
X else if (strcmp(argv[1], "-l") == 0) {argv += 2; argc -= 2;}
X else if (strcmp(argv[1], "-c") == 0)
X {catspec = argv[2]; argv += 2; argc -= 2;}
X else {argv += 1; argc -= 1;}
X }
X
X if (! catspec) {fprintf(stderr, "Missing -c\n"); exit(1);}
X if (! docspec) {fprintf(stderr, "Missing -d\n"); exit(1);}
X
X /*
X * Now look at the document specifier:
X * <bs=SUNWab_2_6;bk=SUNDIAG;dc=1034>
X * bs is the id of the documentset in the card catalog file
X * bk is the individual document
X * dc is a location within the document
X */
X
X bs = getvalue(docspec, "bs=", ";>");
X if (!bs)
X {fprintf(stderr, "-d arg doesn't have bs="); exit(1);}
X bk = getvalue(docspec, "bk=", ";>");
X if (!bk)
X {fprintf(stderr, "-d arg doesn't have bk="); exit(1);}
X dc = getvalue(docspec, "dc=", ";>");
X if (!bs)
X {fprintf(stderr, "-d arg doesn't have dc="); exit(1);}
X
X
X /*
X * Now find an entry in some card catalog whose id matches bs
X */
X
X while (catspec) {
X
X /* loop over catalogs in colon separated list */
X thiscat = catspec;
X catspec = strchr(catspec, ':');
X if (catspec)
X *catspec++ = 0;
X else
X catspec = NULL;
X
X catfile = fopen(thiscat, "r");
X if (! catfile)
X {fprintf(stderr, "Can't open card catalog file %s", thiscat);
exit(1);}
X
X tocpath = NULL;
X while (fgets(buffer, sizeof(buffer) -1, catfile)) {
X buffer[sizeof(buffer)-1] = 0;
X
X /* ignore comment lines */
X if (buffer[0] == '#')
X continue;
X /* get all the continuation lines */
X while (1) {
X i = strlen(buffer);
X if (buffer[i-1] == '\n') {
X buffer[i-1] = 0;
X i--;
X }
X if (buffer[i-1] != '\\')
X break;
X if (! fgets(buffer+i, sizeof(buffer) - 1 - i, catfile))
X {fprintf(stderr, "Continuation at EOF in %s\n", thiscat);
exit(1);}
X }
X
X /* is this the right entry? */
X id = getvalue(buffer, "id=", ":");
X if (!id)
X {fprintf(stderr, "Card catalog %s has line without id= %s\n",
X thiscat, buffer); exit(1);}
X if (strcmp(id, bs) != 0) {
X free(id);
X continue; /* no, try next */
X }
X
X /* yes. Parse the rest of the entry to get tocpath and pspath */
X tocpath = getvalue(buffer, "tocpath=", ":");
X if (!tocpath)
X {fprintf(stderr, "Card catalog %s has line without tocpath= %s\n",
X thiscat, buffer); exit(1);}
X
X pspath = getvalue(buffer, "pspath=", ":");
X if (!pspath)
X {fprintf(stderr, "Card catalog %s has line without pspath= %s\n",
X thiscat, buffer); exit(1);}
X
X }
X fclose(catfile);
X if (tocpath) /* found a matching entry ? */
X break; /* yes */
X /* no, continue with next card catalog in colon-separated list */
X }
X
X if (!tocpath) /* nothing in any card catalog */
X {fprintf(stderr, "Card catalog %s has no entry for %s\n",
X thiscat, id); exit(1);}
X
X#ifdef DEBUG
X printf("bs %s bk %s dc %s tocpath %s pspath %s\n",
X bs, bk, dc, tocpath, pspath);
X#endif
X
X /*
X * Now we've got all the file names and other information.
X * Unfortunately it can be either Solaris 2.2, which uses
X * a netISAM .rec file, or older code, which uses dbm.
X * First see if we've got an ISAM file
X */
X
X sprintf(buffer, "%s/%s.rec", tocpath, bk);
X
X recfile = fopen(buffer, "r");
X if (recfile) {
X /*
X * Yup. I don't have code to process ISAM. I simply read the
X * file sequentially looking for ^A followed by the key. This
X * seems OK in all the examples I've looked at. But I have
X * no idea what the format of an ISAM file is.
X */
X
X ch = getc(recfile);
X while (ch != EOF) {
X if (ch != 1) { /* search for ^A */
X ch = getc(recfile);
X continue;
X }
X cp = buffer; /* copy next characters so we can compare with key */
X while ((ch = getc(recfile)) != EOF) {
X if (ch == 1)
X break;
X *cp++ = ch;
X if ((cp - buffer) > strlen(dc))
X break;
X }
X if (ch == EOF)
X break;
X if (ch == 1) /* another ^A before we got enough characters */
X continue;
X if (strncmp(buffer, dc, strlen(dc)) == 0 &&
X buffer[strlen(dc)] == ' ')
X break; /* key matches */
X }
X if (ch == EOF)
X {fprintf(stderr, "Rec file %s/%s.rec no entry for %s ",
X tocpath, bk, dc); exit(1); }
X fgets(buffer, sizeof(buffer), recfile);
X fclose(recfile);
X } else {
X /*
X * here if no .rec file. Hope it's a DBM file
X */
X sprintf(buffer, "%s/%s", tocpath, bk);
X db = dbm_open(buffer, 0, 0);
X if (! db)
X {fprintf(stderr, "Rec file %s/%s.rec not found\n",
X tocpath, bk); exit(1); }
X memset(&keyst, 0, sizeof(keyst));
X /*
X * bk is always the file name, dc is the key. Normally dc is
X * an integer. But if you choose the cover, they give the
X * name of the whole document as dc. Turns out that is indexed
X * slightly differently
X */
X if (strcmp(dc, bk) == 0)
X sprintf(keyst.stkey, "<%s>", dc);
X else
X sprintf(keyst.stkey, "<%s>%s", bk, dc);
X /*
X * No idea why they don't just use the string as the key, but
X * they make up this odd binary structure with two counts
X */
X keyst.count2 = strlen(keyst.stkey);
X keyst.count1 = keyst.count2 + 1;
X key.dsize = (keyst.count2 + 8 + 3) & 0xfffffffc;
X key.dptr = (char *)&keyst;
X fetch = dbm_fetch(db, key);
X if (fetch.dptr == NULL)
X {fprintf(stderr, "DBM file %s/%s no entry for %s ",
X tocpath, bk, dc); exit(1); }
X i = fetch.dsize;
X if (i > sizeof(buffer))
X i = sizeof(buffer);
X /*
X * There's lots of junk in the data. The only thing I understand
X * is the view: property. I'm going to use strstr to look for it.
X * For that to work, we can't have any nulls, as that will stop
X * the search. Turn nulls into spaces.
X */
X for (cp = buffer, cp2 = fetch.dptr; i > 0; i--) {
X if (*cp2 == 0) {
X *cp++ = ' ';
X cp2++;
X } else
X *cp++ = *cp2++;
X }
X *cp = ' ';
X dbm_close(db);
X }
X
X /*
X * Here with buffer having the description of the entry we're
X * looking for. The format of this is close enough in 2.2
X * and older to use the same code.
X * view:CHAPTER:PAGE
X * CHAPTER is the name of the file containing the chapter
X * PAGE is the page number within the file
X */
X
X#ifdef DEBUG
X printf("%s|\n",buffer);
X#endif
X
X cp = strstr(buffer, "view:");
X if (! cp)
X {fprintf(stderr, "Rec file %s/%s.rec entry for %s has no view: ",
X tocpath, bk, dc); exit(1);}
X
X cp += 5;
X psfile = cp;
X
X cp = strchr(psfile, ':');
X if (!cp)
X {fprintf(stderr, "Rec file %s/%s.rec entry for %s has no page number
1:%s",
X tocpath, bk, dc, psfile); exit(1);}
X *cp++ = 0;
X
X pspage = cp;
X
X cp2 = strchr(cp, ' ');
X if (!cp2)
X {fprintf(stderr, "Rec file %s/%s.rec entry for %s has no page number
2:%s",
X tocpath, bk, dc, cp); exit(1);}
X *cp2 = 0;
X
X /*
X * Now we've got it all. So call ghostview
X */
X
X sprintf(buffer, "%s/%s/%s", pspath, bk, psfile);
X
X /*
X * This seems to be necessary. I'm not sure why..
X */
X maxfd = sysconf(_SC_OPEN_MAX);
X for (i = 3; i < maxfd; i++)
X close(i);
X
X execlp("ghostview", "ghostview", "-page", pspage, buffer, 0);
X
X fprintf(stderr, "Can't exec ghostview\n");
X exit(1);
X
X}
X
SHAR_EOF
$TOUCH -am 0529143095 docviewer.c &&
chmod 0640 docviewer.c ||
echo "restore of docviewer.c failed"
set `wc -c docviewer.c`;Wc_c=$1
if test "$Wc_c" != "10911"; then
echo original size 10911, current size $Wc_c
fi
# ============= answerbook_setup ==============
echo "x - extracting answerbook_setup (Text)"
sed 's/^X//' << 'SHAR_EOF' > answerbook_setup &&
X#!/bin/ksh
X# If we're not using Sun's OpenWindows server, use a low-life emulation
X#
X
Xhasnews=no
Xif xdpyinfo | grep "vendor string:" | grep -s "X11/NeWS" ; then
X hasnews=yes
Xfi
Xexport hasnews
X
XAB_CARDCATALOG="${AB_CARDCATALOG}:\
X/cs/opt/AB/SUNWaadm/ab_cardcatalog:\
X/cs/opt/AB/SUNWabe/ab_cardcatalog:\
X/cs/opt/AB/SUNWabhdw/ab_cardcatalog:\
X/cs/opt/AB/SUNWaman/ab_cardcatalog:\
X/cs/opt/AB/SPROabcc/ab_cardcatalog:\
X/cs/opt/AB/SPROabcpl/ab_cardcatalog:\
X/cs/opt/AB/SPROabins/ab_cardcatalog:\
X/cs/opt/AB/SPROabrm/ab_cardcatalog:\
X/cs/opt/AB/SPROabsw/ab_cardcatalog:\
X/cs/opt/AB/SPROabtw/ab_cardcatalog"
X
Xexport AB_CARDCATALOG
X
X
X
SHAR_EOF
$TOUCH -am 0421115195 answerbook_setup &&
chmod 0755 answerbook_setup ||
echo "restore of answerbook_setup failed"
set `wc -c answerbook_setup`;Wc_c=$1
if test "$Wc_c" != "633"; then
echo original size 633, current size $Wc_c
fi
exit 0

5- Reflection X might support Post Script. It's very expensive,
however!

Regards