SUMMARY II : Answerbook under X11R6

From: Cristian Martinez T. (spy@inf.utfsm.cl)
Date: Fri Apr 12 1996 - 12:33:31 CDT


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



This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:10:57 CDT