685 lines
14 KiB
C
685 lines
14 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these libraries and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/* $XConsortium: BookTasks.cc /main/5 1996/05/29 12:36:58 rcs $
|
|
*
|
|
* (c) Copyright 1996 Digital Equipment Corporation.
|
|
* (c) Copyright 1996 Hewlett-Packard Company.
|
|
* (c) Copyright 1996 International Business Machines Corp.
|
|
* (c) Copyright 1996 Sun Microsystems, Inc.
|
|
* (c) Copyright 1996 Novell, Inc.
|
|
* (c) Copyright 1996 FUJITSU LIMITED.
|
|
* (c) Copyright 1996 Hitachi.
|
|
*/
|
|
|
|
|
|
#include <sstream>
|
|
using namespace std;
|
|
|
|
/* import... */
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
#include "Dispatch.h"
|
|
#include "Token.h"
|
|
#include "OLAF.h"
|
|
#include "NodeTask.h"
|
|
#include "TOCTask.h"
|
|
#include "BookCaseDB.h"
|
|
#include "OL_Data.h"
|
|
#include "StringList.h"
|
|
#include "StyleTask.h"
|
|
#include "api/utility.h"
|
|
|
|
/* export... */
|
|
#include "BookTasks.h"
|
|
|
|
#ifdef LICENSE_MANAGEMENT
|
|
#include "cryptlib/lterms.h"
|
|
#endif
|
|
|
|
#ifdef FISH_DEBUG
|
|
#include "dbug.h" /* ala Fred Fish's dbug package from uunet */
|
|
#endif
|
|
|
|
#ifdef LICENSE_MANAGEMENT
|
|
const int A_FEATURE = OLAF::Feature;
|
|
const int A_VEN_CODE = OLAF::VenCode;
|
|
const int A_VERSION = OLAF::Version;
|
|
const int A_GROUPING = OLAF::Grouping;
|
|
const int A_DEMO_TERMS = OLAF::DemoTerms;
|
|
const int A_DEFAULT_SECTION = OLAF::DefaultSection;
|
|
#endif
|
|
|
|
/***********************************
|
|
*
|
|
* BookCaseTask
|
|
*
|
|
***********************************/
|
|
|
|
BookCaseTask::BookCaseTask(const char *infolib)
|
|
{
|
|
int len = strlen(infolib);
|
|
library = new char[len + 1];
|
|
*((char *) memcpy(library, infolib, len) + len) = '\0';
|
|
|
|
f_base = -1;
|
|
|
|
bookCaseName = NULL;
|
|
bookCaseDesc = NULL;
|
|
|
|
f_db = NULL;
|
|
|
|
if ( !Dispatch::RunTocGenOnly() ) {
|
|
style = new StyleTaskDB(this);
|
|
addSubTask(style);
|
|
} else {
|
|
style = NULL;
|
|
}
|
|
|
|
book = new BookTask(this);
|
|
addSubTask(book);
|
|
|
|
f_style = NULL;
|
|
f_search_storage = NULL;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
BookCaseDB*
|
|
BookCaseTask::database()
|
|
{
|
|
if(!f_db){
|
|
f_db = new BookCaseDB(library);
|
|
}
|
|
|
|
return f_db;
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
DBTable *
|
|
BookCaseTask::table(int tid)
|
|
{
|
|
return database()->table(tid);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
const char *
|
|
BookCaseTask::bookcasename()
|
|
{
|
|
if ( !bookCaseName ) {
|
|
throw(Unexpected("BookCase name not available yet."));
|
|
}
|
|
|
|
return ( bookCaseName->content() );
|
|
}
|
|
|
|
/*
|
|
//--------------------------------------------------------------------
|
|
void
|
|
BookCaseTask::write_full_text_record( const char *str,
|
|
int sz,
|
|
const char *nodelocator,
|
|
const char *node_title
|
|
)
|
|
{
|
|
const char *BookCaseName = bookcasename();
|
|
|
|
if ( !f_search_storage ) {
|
|
const char *pathname = database()->path();
|
|
|
|
f_search_storage = new FulcrumStore( pathname , BookCaseName);
|
|
assert ( f_search_storage );
|
|
}
|
|
|
|
const int BookNum = book->sequencenum();
|
|
const char *BookShortTitle = book->book_short_title();
|
|
|
|
f_search_storage->insert( BookCaseName,
|
|
BookNum,
|
|
BookShortTitle,
|
|
nodelocator,
|
|
node_title,
|
|
str,
|
|
sz );
|
|
}
|
|
*/
|
|
/*
|
|
//--------------------------------------------------------------------
|
|
void
|
|
BookCaseTask::write_full_text_record(DataRepository *store,
|
|
const char *nodelocator,
|
|
const char *node_title
|
|
)
|
|
{
|
|
|
|
const char *BookCaseName = bookcasename();
|
|
|
|
if ( !f_search_storage ) {
|
|
const char *pathname = database()->path();
|
|
f_search_storage = new AusTextStore( pathname, BookCaseName );
|
|
assert( f_search_storage );
|
|
}
|
|
|
|
const char *BookShortTitle = book->book_short_title();
|
|
f_search_storage->insert( BookShortTitle,
|
|
nodelocator,
|
|
node_title,
|
|
store
|
|
);
|
|
}
|
|
|
|
*/
|
|
|
|
//--------------------------------------------------------------------
|
|
void BookCaseTask::markup(const Token &t)
|
|
{
|
|
ComplexTask::markup(t);
|
|
|
|
if (t.type() == START){
|
|
|
|
if(t.olaf() == OLAF::Bookcase){
|
|
if(f_base >= 0){
|
|
throw(Unexpected("second (illegal) BookCase element found"));
|
|
}
|
|
|
|
f_base = t.level();
|
|
}
|
|
|
|
if(f_base >= 0){
|
|
switch(t.olaf()){
|
|
|
|
case OLAF::BcName:
|
|
if(bookCaseName){
|
|
throw(Unexpected("second (illegal) bookcase name element found"));
|
|
}
|
|
|
|
bookCaseName = new OL_Data(t, OLAF::OL_data);
|
|
addSubTask(bookCaseName);
|
|
break;
|
|
|
|
case OLAF::BcDesc:
|
|
if(bookCaseDesc){
|
|
throw(Unexpected("second (illegal) bookcase description element found"));
|
|
}
|
|
|
|
bookCaseDesc = new OL_Data(t, OLAF::OL_data);
|
|
addSubTask(bookCaseDesc);
|
|
break;
|
|
|
|
}
|
|
|
|
if(!f_style && t.LookupAttr(OLAF::OL_style)){
|
|
OL_Data *tmp_style = new OL_Data(t, OLAF::OL_style);
|
|
if ( tmp_style->DataWillBeAvailable() ) {
|
|
f_style = tmp_style;
|
|
addSubTask(f_style);
|
|
}
|
|
else {
|
|
delete tmp_style;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
else if(t.type() == END){
|
|
|
|
if(t.level() == f_base){
|
|
const char *name;
|
|
const char *desc;
|
|
|
|
if(bookCaseName){
|
|
name = bookCaseName->content();
|
|
}else{
|
|
throw(Unexpected("No bookcase name element in Bookcase element."));
|
|
}
|
|
|
|
if(bookCaseDesc){
|
|
desc = bookCaseDesc->content();
|
|
}else{
|
|
desc = "";
|
|
}
|
|
|
|
printf("BookCase name: `%s' desc: `%s'\n", name, desc);
|
|
}
|
|
|
|
/* @# warn if no bookcase ever found? */
|
|
}
|
|
}
|
|
|
|
|
|
const char *
|
|
BookCaseTask::styleName()
|
|
{
|
|
const char *ret;
|
|
|
|
if ( Dispatch::RunTocGenOnly() ) {
|
|
return("");
|
|
}
|
|
|
|
if(!f_style) {
|
|
throw(Unexpected ("No style architectural form defined for bookcase."));
|
|
}
|
|
|
|
ret = f_style->content();
|
|
|
|
#ifdef FISH_DEBUG
|
|
DBUG_PRINT("Style", ("bookcase style is: %s", ret));
|
|
#endif
|
|
|
|
if(!style->exist(ret)){
|
|
#ifdef FISH_DEBUG
|
|
DBUG_PRINT("Error", ("style `%s' not found", ret));
|
|
#endif
|
|
Token::signalError(Token::User, Token::Fatal, NULL, 0,
|
|
"An undeclared style sheet name `%s' was found in the bookcase specification.\n", ret);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*****************
|
|
*
|
|
* BookTask
|
|
*
|
|
*****************/
|
|
|
|
BookTask::BookTask(BookCaseTask *bc)
|
|
{
|
|
f_base = 0;
|
|
f_seq_no = 1;
|
|
|
|
f_toc = NULL;
|
|
f_bookcase = bc;
|
|
|
|
tocLocator = NULL;
|
|
|
|
shortTitle = NULL;
|
|
title = NULL;
|
|
|
|
tabName = NULL;
|
|
tabLocator = NULL;
|
|
|
|
tabNames = new StringList();
|
|
tabLocators = new StringList();
|
|
tabLines = new StringList();
|
|
tabFiles = new StringList();
|
|
|
|
f_node = new NodeTask(this, NULL);
|
|
addSubTask(f_node);
|
|
|
|
f_style = NULL;
|
|
|
|
e_string = NULL;
|
|
e_len = 0;
|
|
}
|
|
|
|
|
|
BookTask::~BookTask()
|
|
{
|
|
KILLSUBTASK(f_node);
|
|
|
|
delete tabLocators;
|
|
|
|
KILLSUBTASK(title);
|
|
KILLSUBTASK(shortTitle);
|
|
KILLSUBTASK(tabName);
|
|
KILLSUBTASK(tabLocator);
|
|
|
|
}
|
|
|
|
//------------------------------------------------------------------
|
|
void
|
|
BookTask::encrypt( const Token &t )
|
|
{
|
|
/*
|
|
* Grab all the strings that are required by the encryption API
|
|
*/
|
|
|
|
char buf[ 256 ];
|
|
|
|
#ifdef LICENSE_MANAGEMENT
|
|
LTerms lt;
|
|
|
|
char *a_val;
|
|
|
|
for ( const AttributeRec *arec = t.GetFirstAttr();
|
|
arec;
|
|
arec = t.GetNextAttr( arec ) ) {
|
|
|
|
a_val = ( char * )arec->getAttrValueString();
|
|
|
|
#ifdef FISH_DEBUG
|
|
DBUG_PRINT("BookTasks", ("access attribute value %s", a_val) );
|
|
#endif
|
|
|
|
switch ( arec->getAttrName() ) {
|
|
|
|
case A_FEATURE :
|
|
|
|
if ( lt.add_feature( a_val ) != 0 ) {
|
|
throw(Unexpected("invalid access feature syntax"));
|
|
}
|
|
break;
|
|
|
|
case A_VEN_CODE :
|
|
if ( lt.add_ven_code( a_val ) != 0 ) {
|
|
throw(Unexpected("invalid access ven_code syntax") );
|
|
}
|
|
break;
|
|
|
|
case A_VERSION :
|
|
if ( lt.add_version( a_val ) != 0 ) {
|
|
throw(Unexpected("invalid access version syntax"));
|
|
}
|
|
break;
|
|
|
|
case A_GROUPING :
|
|
if ( lt.add_grouping( a_val ) != 0 ) {
|
|
throw(Unexpected("invalid access grouping syntax"));
|
|
}
|
|
break;
|
|
|
|
case A_DEMO_TERMS :
|
|
|
|
if ( lt.add_demo_terms( a_val ) != 0 ) {
|
|
throw(Unexpected("invalid access demo_terms syntax"));
|
|
}
|
|
break;
|
|
|
|
case A_DEFAULT_SECTION :
|
|
|
|
if ( lt.add_noaccess_locator( a_val ) != 0 ) {
|
|
throw(Unexpected("invalid default section ID syntax"));
|
|
}
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
if ( lt.pack( buf, 256 ) ) {
|
|
throw(Unexpected("Unable to pack the string for encryption"));
|
|
}
|
|
|
|
int len = 256;
|
|
if ( e_terms( <, buf, len ) ) {
|
|
throw(Unexpected("Unable to encrypt string for access control"));
|
|
}
|
|
#else
|
|
int len = 256;
|
|
(void) memset(buf, '\0', len);
|
|
#endif
|
|
|
|
e_string = (char *)malloc(len);
|
|
(void)memcpy(e_string, buf, len); // Cannot use strdup - embedded NULs
|
|
e_len = len;
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
void BookTask::markup(const Token &t)
|
|
{
|
|
ComplexTask::markup(t);
|
|
|
|
if(t.type() == START){
|
|
|
|
if(t.olaf() == OLAF::Book){
|
|
if(f_base > 0){
|
|
throw(Unexpected("illegal nested BOOK architectural form"));
|
|
}
|
|
|
|
f_base = t.level();
|
|
}
|
|
|
|
if(f_base >= 0){
|
|
switch(t.olaf()){
|
|
case OLAF::BkSTitle:
|
|
if(shortTitle){
|
|
throw(Unexpected("BkSTitle already found"));
|
|
}
|
|
|
|
shortTitle = new OL_Data(t, OLAF::OL_data);
|
|
addSubTask(shortTitle);
|
|
break;
|
|
|
|
case OLAF::BkTitle:
|
|
if(title){
|
|
throw(Unexpected("BkTitle already found"));
|
|
}
|
|
|
|
title = new OL_Data(t, OLAF::OL_data);
|
|
addSubTask(title);
|
|
break;
|
|
|
|
case OLAF::Tab:
|
|
if(tabName){
|
|
tabNames->append(tabName->content());
|
|
tabLocators->append(tabLocator->content());
|
|
tabLines->append( form("%d", tabLocator->line_no()) );
|
|
tabFiles->append( tabLocator->filename() );
|
|
|
|
KILLSUBTASK(tabName);
|
|
KILLSUBTASK(tabLocator);
|
|
}
|
|
|
|
tabName = new OL_Data(t, OLAF::OL_data);
|
|
tabLocator = new OL_Data(t, OLAF::OL_idref, REMOVE_SPACES);
|
|
addSubTask(tabName);
|
|
addSubTask(tabLocator);
|
|
break;
|
|
|
|
case OLAF::BookAccess:
|
|
encrypt( t );
|
|
break;
|
|
}
|
|
|
|
if ( t.LookupAttr( OLAF::OL_ToC ) ) {
|
|
if ( f_toc ) {
|
|
throw(Unexpected("An illegal TOC was found.\n"));
|
|
}
|
|
|
|
f_toc = new TOCTask(t, this);
|
|
addSubTask(f_toc);
|
|
}
|
|
|
|
if(f_base >= 0 && !f_style && t.LookupAttr(OLAF::OL_style)){
|
|
OL_Data *tmp_style = new OL_Data(t, OLAF::OL_style);
|
|
if ( tmp_style->DataWillBeAvailable() ) {
|
|
f_style = tmp_style;
|
|
addSubTask(f_style);
|
|
}
|
|
else {
|
|
delete tmp_style;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
else if(t.type() == END){
|
|
if(t.level() == f_base){ /* found end of book... write out CCF data */
|
|
if ( !Dispatch::RunTocGenOnly() ) {
|
|
write_record();
|
|
}
|
|
|
|
reset();
|
|
}
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
void BookTask::write_record(void)
|
|
{
|
|
StringList tablines;
|
|
|
|
/* finish any pending tab */
|
|
if(tabName){
|
|
tabNames->append(tabName->content());
|
|
tabLocators->append(tabLocator->content());
|
|
tabLines->append( form("%d", tabLocator->line_no()) );
|
|
tabFiles->append(tabLocator->filename());
|
|
}
|
|
|
|
for(unsigned int i = 0; i < tabNames->qty(); i++){
|
|
const char *name = tabNames->item(i);
|
|
const char *loc = tabLocators->item(i);
|
|
const char *line = tabLines->item(i);
|
|
const char *file = tabFiles->item(i);
|
|
|
|
int plen = strlen(name) + 1 + strlen(loc) + 1
|
|
+ strlen(line) + 1 + strlen(file) + 1;
|
|
char *p = new char [plen];
|
|
|
|
snprintf(p, plen, "%s\t%s\t%s\t%s", name, loc, line, file);
|
|
tablines.append(p);
|
|
|
|
delete [] p;
|
|
}
|
|
|
|
const char *bk_title;
|
|
|
|
if(title){
|
|
bk_title = title->content();
|
|
}else{
|
|
throw(Unexpected("Required Title form missing from Book"));
|
|
}
|
|
|
|
const char *bk_stitle = bk_title;
|
|
|
|
if ( shortTitle ) {
|
|
bk_stitle = shortTitle->content();
|
|
}
|
|
|
|
DBTable *tbl = bookcase()->table(BookCaseDB::BookMeta);
|
|
|
|
tbl->insert(STRING_CODE, locator(),
|
|
STRING_CODE, bk_stitle,
|
|
STRING_CODE, bk_title,
|
|
INTEGER_CODE, f_seq_no,
|
|
SHORT_LIST_CODE, tablines.qty(), STRING_CODE, tablines.array(),
|
|
-STRING_CODE, e_string , (size_t)e_len,
|
|
NULL);
|
|
|
|
#ifdef FISH_DEBUG
|
|
DBUG_PRINT("Book", ("Book... title: `%s' short title: `%s'\n",
|
|
bk_title,
|
|
bk_stitle));
|
|
#endif
|
|
}
|
|
|
|
|
|
void BookTask::reset()
|
|
{
|
|
KILLSUBTASK(shortTitle);
|
|
KILLSUBTASK(title);
|
|
KILLSUBTASK(f_toc);
|
|
KILLSUBTASK(f_style);
|
|
|
|
delete tabNames; tabNames = new StringList();
|
|
delete tabLocators; tabLocators = new StringList();
|
|
|
|
tabName = tabLocator = NULL;
|
|
|
|
delete tabLines; tabLines = new StringList();
|
|
delete tabFiles; tabFiles = new StringList();
|
|
|
|
delete [] tocLocator; tocLocator = NULL;
|
|
|
|
|
|
f_seq_no ++;
|
|
f_base = 0;
|
|
|
|
}
|
|
|
|
|
|
const char *BookTask::locator()
|
|
{
|
|
|
|
if ( Dispatch::RunTocGenOnly() ) {
|
|
return ("");
|
|
}
|
|
|
|
if(!tocLocator){
|
|
/* this is the first time anybody asked for the book's locator...
|
|
* it must be the TOC node asking for the book locator, which
|
|
* is the TOC node locator!
|
|
*/
|
|
const char *l = f_node->locator();
|
|
int len = strlen(l);
|
|
tocLocator = new char[len + 1];
|
|
*((char *) memcpy(tocLocator, l, len) + len) = '\0';
|
|
}
|
|
|
|
return tocLocator;
|
|
}
|
|
|
|
|
|
const char *
|
|
BookTask::styleName()
|
|
{
|
|
if ( Dispatch::RunTocGenOnly() ) {
|
|
return("");
|
|
}
|
|
|
|
const char *ret;
|
|
if(f_style){
|
|
ret = f_style->content();
|
|
|
|
if(f_bookcase->styleTask()->exist(ret)){
|
|
#ifdef FISH_DEBUG
|
|
DBUG_PRINT("Style", ("book style is: %s", ret));
|
|
#endif
|
|
}else{
|
|
Token::signalError(Token::User, Token::Continuable, NULL, 0,
|
|
"no such style `%s'\n", ret);
|
|
ret = f_bookcase->styleName();
|
|
}
|
|
}else{
|
|
ret = f_bookcase->styleName();
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
const char *
|
|
BookTask::book_title()
|
|
{
|
|
if ( !title ) {
|
|
throw(Unexpected("Book title is not available yet"));
|
|
}
|
|
|
|
return( title->content() );
|
|
}
|
|
|
|
//--------------------------------------------------------------
|
|
const char *
|
|
BookTask::book_short_title()
|
|
{
|
|
if ( !shortTitle ) {
|
|
return( book_title() );
|
|
}
|
|
|
|
return( shortTitle->content() );
|
|
}
|
|
|