From: SMTP%"VMSSERV@kcl.ac.uk" 19-AUG-1996 18:16:02.98 To: everhart@star.zko.dec.com CC: Subj: WEBBOOK.5-OF-5 -+-+-+-+-+-+-+-+ START OF PART 5 -+-+-+-+-+-+-+-+ X/********\0808\1010\2020\400C/ X/* Convert strings containing punctuation characters into escaped\3708. X */ Xstatic char *escape_string (\1607source ) X`7B X int i, j, punct_count; X char *dest; X dest = source; X punct_count = 0; X for ( i = 0; source`5Bi`5D; i++ ) if ( ispunct ( \2009 ) ) `7B X`09if ( (source`5Bi`5D != '.') `26`26\1610$') )punct_count++; X `7D else if ( isspace ( source`5Bi`5D ) ) punct_count++; X X if ( punct_count > 0 ) `7B X`09dest = malloc ( i + punct_count*3 + 1 ); X`09if ( !dest ) return source; X X`09for ( i = j = 0; source`5Bi`5D; i++ ) `7B X`09 if ( isspace(source`5Bi`5D) `7C`7C (ispunct ( \1909 ) `26`26 X`09`09`09(source`5Bi`5D != '.') `26`26 \160F$')) ) `7B X`09`09sprintf ( `26dest`5Bj`5D, "%%%02x", source`5Bi`5D ); X`09`09if ( dest`5Bj+1`5D == ' ' )\130C '0'; X`09`09j += 3; X`09 `7D else X`09`09dest`5Bj++`5D = source`5Bi`5D; X`09`7D X`09dest`5Bj`5D = '`5C0'; X `7D X return dest; X`7D $ call unpack [.WEBBOOK]WEBBOOK.C;1 - 577315651 "FORMAT STREAM_LF;CARRIAGE_CONTROL CARRIAGE_RETURN" 50 16 20 $! $ create 'f' Xwebbook,\0807_shelf,bookfile_section\110Aindex\0F0Bo Xbookfile_text,\0E09figure $ call unpack [.WEBBOOK]WEBBOOK.OPT;1 - 908017559 "FORMAT STREAM_LF;CARRIAGE_CONTROL CARRIAGE_RETURN" 1 17 20 $! $ create 'f' X/* X * This module is called by the webbook main routine sees a path_info X * string ending in slash, implying that the the atarget is a shelf. X * The main routine deletes the trailing slash and pass\1E07path as an X * argument to webbook_shelf(). This string is assumed to be the name of X * the bookshelf file to read (default decw$book:library.\1209shelf). `20 X * Succeeding elements are used to hold the history of which shelves were`20 X * travered to get to the current shelf. X * X * Conditional compilation symbols: X * NOCGILIB X */ X#include X#include X#include X#include X X#ifdef NOCGILIB X#include X#define cgi_printf \0706 X#define cgi_info(a) getenv(strcpy(`26\1B08_buf`5B4`5D,a)-4) Xstatic char cgi_info_buf`5B64`5D = `7B 'W', 'W',\0A07_' `7D; X#else X#include "cgilib.h" X#endif X X#define SHELF_ICON "" X#define BOOK_ICON "" X Xstruct shelf_rec `7B X struct shelf_rec *next; X char *type;`09`09/* first element. */ X char *fname; X char *desc; X`7D; Xtypedef struct shelf_rec *\0B09p; X Xstatic shelf_recp get_\0F09 ( FILE *sf,\250Cprev ); Xstatic char *escape_string (\1607 ); Xstatic char *entify_string (\1607 ); Xstatic char *apply_default (\1607fname,\2307def\0F0Cout ); Xstatic int send_http_header ( char *stsline,\0F07content ); X Xint webbook_shelf ( char *path,\0C07software_version ) X`7B X char *title, *script_name, *elem`5B20`5D; X int status, i, j, lvl; X FILE *sf; X struct shelf_rec *rec, first_rec; X char shelf_spec`5B256`5D; X char shelf_history`5B2048`5D; X /* X * Parse the path elements. X */ X strncpy ( shelf_history, path, sizeof(\1C0D)-1 ); X path = shelf_history; X path`5Bsizeof(shelf_history)-1`5D = '`5C0'; X if ( *path == '/' ) path++; X elem`5B0`5D = path; X for ( j = i = 0; path`5Bi`5D; i++ ) if ( \1407 == '/' ) `7B X`09path`5Bi`5D = '`5C0'; X`09j++; X`09elem`5Bj`5D = `26path`5Bi+1`5D; X`09if ( j >= 19 ) break; X `7D X /* X * Attempt to open the shelf file and parse. X */ X first_rec.next = (shelf_recp) 0; X first_rec.type = ""; X rec = `26first_rec; X title = path; X#ifdef VERBOSE Xprintf("`5Cn", path, j, elem V`5Bj`5D ); X#endif X sf = fopen ( elem`5Bj`5D, "r", "dna=decw$book:library.\1209shelf", "mbc=64" V ); X if ( sf ) `7B X`09while ( rec = get_shelf_rec ( sf, rec ) ) `7B X`09 if ( 0 == strcmp ( rec->type, "TITLE" ) ) `7B X`09`09title = rec->desc; X`09 `7D X`09`7D X`09fgetname(sf, shelf_spec, 1);`09/* full file name of bookshelf */ X`09fclose ( sf ); X `7D X /* X * Generate HTML header. X */ X send_http_header ( "200 Sending generated HTML`5Cn", "Text/html" ); X cgi_printf("`5Cn%s</\0A06`5Cn", entify_string(title) ); V X cgi_printf("<!-- Software: %s -->`5Cn</HEAD>", s\1C07_version ); X cgi_printf("<BODY>`5Cn<H2>%s</H2><P>`5Cn", path); X script_name = cgi_info ( "SCRIPT_NAME" ); X /* X * Generate history path. X */ X lvl = 2; X for ( i = 1; i < j; i++ ) `7B X`09lvl++; X`09if ( lvl > 6 ) lvl = 6; X`09cgi_printf ( "<H%d>%s</H%d>`5Cn", lvl, entify_string(elem`5Bi`5D), lvl ); X `7D X cgi_printf("<BR><HR>`5Cn"); X /* X * Generate directory with links to each. X */ X if ( ! first_rec.next ) `7B X`09cgi_printf ( "Error opening bookshelf file %s`5Cn", path); X `7D X for ( rec = first_rec.next; rec; rec = rec->next ) `7B X`09char *escaped_target,\110Adesc, *entified; X`09char target`5B256`5D; X`09apply_default ( rec->fname, shelf_spec, target ); X`09entified = entify_string(rec->desc); X`09escaped_target = \1106_string(\1706); X`09if ( 0 == strcmp ( rec->type, "SHELF" ) ) `7B X`09 escaped_desc =\0F07_string(rec->desc); X`09 cgi_printf("%s <A HREF=`5C"../%s/%s/`5C">%s</A><BR>`5Cn", SHELF_ICON,`20 V X`09`09escaped_desc, \0E08target, entified ); X`09 free ( escaped_desc ); X`09`7D else if ( 0 == strcmp ( rec->type, "BOOK" ) ) `7B X`09 cgi_printf("%s <A HREF=`5C"%s/%s`5C">%s</A><BR>`5Cn", BOOK_ICON,`20 X`09`09`09script_name, escaped_target, entified ); X`09`7D X`09free ( escaped_target ); X`09free ( entified ); X `7D X cgi_printf ( "</BODY></HTML>`5Cn" ); X return 1; X`7D X/********\0808\1010\2020\400C/ X/* Convert strings containing punctuation characters into escaped\3708. X */ Xstatic char *escape_string (\1607source ) X`7B X int i, j, punct_count; X char *dest; X dest = source; X punct_count = 0; X for ( i = 0; source`5Bi`5D; i++ ) if ( ispunct ( \2009 ) ) `7B X`09if ( (source`5Bi`5D != '.') `26`26\1610$') )punct_count++; X `7D else if ( isspace ( source`5Bi`5D ) ) punct_count++; X X if ( punct_count > 0 ) `7B X`09dest = malloc ( i + punct_count*3 + 1 ); X`09if ( !dest ) return source; X X`09for ( i = j = 0; source`5Bi`5D; i++ ) `7B X`09 if ( isspace(source`5Bi`5D) `7C`7C (ispunct ( \1909 ) `26`26 X`09`09`09(source`5Bi`5D != '.') `26`26 \160F$')) ) `7B X`09`09sprintf ( `26dest`5Bj`5D, "%%%02x", source`5Bi`5D ); X`09`09if ( dest`5Bj+1`5D == ' ' )\130C '0'; X`09`09j += 3; X`09 `7D else X`09`09dest`5Bj++`5D = source`5Bi`5D; X`09`7D X`09dest`5Bj`5D = '`5C0'; X `7D X return dest; X`7D X/********\0808\1010\2020\400C/ X/* Convert strings containing punctuation characters into escaped\3708. X */ Xstatic char *entify_string (\1607source ) X`7B X int i, j,brack_count; X char *dest; X dest = source; X brack_count = 0; X for ( i = 0; source`5Bi`5D; i++ ) `7B X`09if ( (source`5Bi`5D == '<') `7C`7C\1610>') &027C X`09 (source`5Bi`5D == '`26') ) brack_count++; X `7D X if ( brack_count > 0 ) `7B X`09dest = malloc ( i + brack_count*4 + 1 ); X`09if ( !dest ) return source; X X`09for ( i = j = 0; source`5Bi`5D; i++ ) `7B X`09 if ( source`5Bi`5D == '<' ) `7B X`09`09dest`5Bj++`5D = '`26'; X`09`09dest`5Bj++`5D = 'l'; X`09`09dest`5Bj++`5D = 't'; X`09`09dest`5Bj++`5D = ';'; X`09 `7D else if ( source`5Bi`5D == '>' ) `7B X`09`09dest`5Bj++`5D = '`26'; X`09`09dest`5Bj++`5D = 'g'; X`09`09dest`5Bj++`5D = 't'; X`09`09dest`5Bj++`5D = ';'; X`09 `7D else if ( source`5Bi`5D == '`26' ) `7B X`09`09dest`5Bj++`5D = '`26'; X`09`09dest`5Bj++`5D = 'a'; X`09`09dest`5Bj++`5D = 'm'; X`09`09dest`5Bj++`5D = 'p'; X`09`09dest`5Bj++`5D = ';'; X`09 `7D else X`09`09dest`5Bj++`5D = source`5Bi`5D; X`09`7D X`09dest`5Bj`5D = '`5C0'; X `7D X return dest; X`7D X/********\0808\1010\2020\400C/ X/* Read next record from bookshelf file and copy to structure. X */ Xstatic shelf_recp get_\0F09 ( FILE *sf,\250Cprevious ) X`7B X int i,j; X shelf_recp cur; X char *line, tline`5B4096`5D; X /* X * Be optimistice and allocate new structure. X */ X cur = malloc ( sizeof(struct shelf_rec) ); X if ( !cur ) return cur; X cur->next = (shelf_recp) 0; X cur->type =\0C06fnam\0D09desc = ""; X X if ( fgets ( tline, sizeof(tline)-1, sf ) ) `7B X`09/* X`09 * Copy and Parse the record on backslashes. X`09 */ X`09for ( i = 0; i < sizeof(tline) `26`26 tline`5Bi`5D\0C0C != '`5Cn'; i++ ); X`09line = malloc ( i + 1 ); X`09strncpy ( line, t\0706i ); X`09if ( !line ) return (shelf_recp) 0; X`09line`5Bi`5D = '`5C0'; X X`09cur->type = line; X`09for ( j = i = 0; line`5Bi`5D; i++ ) if ( \1407 == '`5C`5C' ) `7B X`09 line`5Bi`5D = '`5C0'; X`09 if ( j == 0 ) `7B X`09`09cur->fname = `26line`5Bi+1`5D; X`09`09j++; X`09 `7D else `7B X`09`09cur->desc = `26line`5Bi+1`5D;&0209/* rest of line */ X`09`09break; X`09 `7D X`09`7D X`09/* X`09 * Unescape characters and upcase type. X`09 */ X`09for ( i = 0; line`5Bi`5D; i++ )`20 X`09`09if ( islower(line`5Bi`5D) ) \0B07 = _toupp\1E0B; X`09 X `7D else `7B X`09/* X`09 * Read error, return null. X`09 */ X`09free ( cur ); X`09cur = (shelf_recp) 0; X `7D X /* X * append new record to list. X */ X previous->next = cur; X return cur; X`7D X/********\0808\1010\2020\400A/ X/* Prepare to send back response. Build standard \1A08 header. X */ Xstatic int send_http_header ( char *stsline,\0F07content ) X`7B X int status; X /* X */ X cgi_printf ( "Content-type: %s`5Cn", c\1506 ); X cgi_printf ( "status: %s`5Cn`5Cn", stsline ); X return 1; X`7D X/********\0808\1010\2020\400A/ X/* Take default directory from defname and apply to fname. X */ Xstatic char *apply_default (\1607fname,\2307def\0F0Cout ) X`7B X int i, d_limit; X X for ( d_limit = i = 0; defname`5Bi`5D; i++ ) `7B X`09if ( defname`5Bi`5D == ':' `7C`7C\1510`5D\1514>' ) X`09 d_limit = i+1; X `7D X if ( d_limit == 0 ) `7B X`09defname = "decw$book:"; X`09d_limit = 10; X `7D X for ( i = 0; fname`5Bi`5D; i++ ) `7B X`09if ( fname`5Bi`5D == ':' `7C`7C\130E`5D\1312>' ) X`09 d_limit = 0; X `7D X if ( d_limit ) strncpy ( out, defname, d\2208; X if ( i+d_limit > 255 ) i = 255-\1807; X strncpy ( `26out`5Bd_limit`5D, fname, i ); X out`5Bi+d_limit`5D = '`5C0'; X return out; X`7D $ call unpack [.WEBBOOK]WEBBOOK_SHELF.C;1 - 1714547544 "FORMAT STREAM_LF;CARRIAGE_CONTROL CARRIAGE_RETURN" 18 18 20 $! $ create 'f' X#define book_width 16 X#define book_height 16 Xstatic char book_bits`5B`5D = `7B X 0x10, 0x18, 0x08, 0x1e, 0x84, 0x1f, 0xee, 0x17\0C0B9, 0x6\1806e, X 0xae, 0x1f, 0xe\0C0C\1818\3014 X 0xee, 0x1f, 0x\0C0607\0C0B1, 0x6\18060`7D; X $ call unpack [.WEBBOOK.HTTP.SERVERDOC]BOOK.XBM;1 - 359208094 "FORMAT STREAM_LF;CARRIAGE_CONTROL CARRIAGE_RETURN" 1 19 20 $! $ create 'f' X#define shelf_width 16 X#define shelf_height 16 Xstatic char shelf_bits`5B`5D = `7B X 0xe0, 0x0f, 0x\0C0C00, 0x1c, 0xee, 0x1d\0C0B9\180A39, X 0xee, 0x39, 0x\0C071\0C0A7\0C0C\180B6\240Be1, X 0xee, 0xe1, 0x0e, 0xc0, 0xe\0C061, 0xff\0606`7D; X $ call unpack [.WEBBOOK.HTTP.SERVERDOC]SHELF.XBM;1 - 503715309 "FORMAT STREAM_LF;CARRIAGE_CONTROL CARRIAGE_RETURN" 1 20 20 $ v=f$verify(v) $ exit ================== RFC 822 Headers ================== Return-Path: VMSSERV@kcl.ac.uk Received: by galaxy.zko.dec.com (UCX V4.0-10B, OpenVMS V6.2 VAX); Mon, 19 Aug 1996 18:15:53 -0400 Received: from newt.kcl.ac.uk by mail11.digital.com (8.7.5/UNX 1.2/1.0/WV) id SAA14620; Mon, 19 Aug 1996 18:03:22 -0400 (EDT) Received: from alder.cc.kcl.ac.uk by newt.kcl.ac.uk with SMTP (PP) id <23302-0@newt.kcl.ac.uk>; Mon, 19 Aug 1996 23:03:04 +0100 Received: by alder.cc.kcl.ac.uk (MX V4.2 AXP) id 731; Mon, 19 Aug 1996 23:03:25 EDT Date: Mon, 19 Aug 1996 23:03:11 BST From: Kings College London File Server <VMSSERV@kcl.ac.uk> To: everhart@star.zko.dec.com Message-ID: <009A71AB.0EE7B920.731@alder.cc.kcl.ac.uk> Subject: WEBBOOK.5-OF-5