home *** CD-ROM | disk | FTP | other *** search
- /* $Header: rthreads.c,v 4.3.3.3 91/01/16 03:28:53 davison Trn $
- **
- ** $Log: rthreads.c,v $
- ** Revision 4.3.3.3 91/01/16 03:28:53 davison
- ** Changed Free to safefree. Tweaked fopen for possible binary open mode.
- **
- ** Revision 4.3.3.2 90/08/20 16:58:14 davison
- ** Added message for missing/bad db.init file.
- **
- ** Revision 4.3.3.1 90/06/20 23:00:28 davison
- ** Initial Trn Release
- **
- */
-
- #include "EXTERN.h"
- #include "common.h"
- #include "intrp.h"
-
- #ifdef USETHREADS
- #include "INTERN.h"
- #include "rthreads.h"
-
- static FILE *fp_in;
-
- static char *strings = Nullch;
-
- static int read_item();
- static void wp_bmap(), lp_bmap();
- static void safefree();
-
- /* Initialize our thread code by determining the byte-order of the thread
- ** files and our own current byte-order. If they differ, set flags to let
- ** the read code know what we'll need to translate.
- */
- void
- thread_init()
- {
- char *filename;
- int i;
-
- word_same = long_same = TRUE;
- filename = filexp( "%X/db.init" );
- if( (fp_in = fopen( filename, FOPEN_RB )) != Nullfp ) {
- if( fread( &mt_bmap, 1, sizeof (BMAP), fp_in ) >= sizeof (BMAP)-1 ) {
- if( mt_bmap.version != DB_VERSION ) {
- printf( "\nThread database is the wrong version -- ignoring it.\n" ) FLUSH;
- use_threads = FALSE;
- }
- mybytemap( &my_bmap );
- for( i = 0; i < sizeof (LONG); i++ ) {
- if( i < sizeof (WORD) ) {
- if( my_bmap.w[i] != mt_bmap.w[i] ) {
- word_same = FALSE;
- }
- }
- if( my_bmap.l[i] != mt_bmap.l[i] ) {
- long_same = FALSE;
- }
- }
- } else {
- goto no_db_init;
- }
- fclose( fp_in );
- } else {
- no_db_init:
- printf( "\ndb.init read failed -- assuming no byte-order translations.\n\n" ) FLUSH;
- }
- }
-
- /* Open a thread file for the sole purpose of using it in a newsreader-
- ** style application. Everything is read into arrays in chunks and some
- ** useful massaging of the data is performed to make the newsreader's life
- ** easier. Be sure to call unuse_data() before calling this a second time.
- */
- int
- use_data( threadname )
- char *threadname;
- {
- register int i, j, k;
- register char *ptr;
-
- if( (fp_in = fopen( threadname, FOPEN_RB )) == Nullfp ) {
- if (errno != ENOENT) {
- printf( "\n\nOpen failed for thread data -- continuing unthreaded.\n" );
- }
- bzero( &total, sizeof (TOTAL) );
- return 0;
- }
- if( fread( &total, 1, sizeof (TOTAL), fp_in ) < sizeof (TOTAL) ) {
- printf( "\n\nRead failed for thread data -- continuing unthreaded.\n" );
- fclose( fp_in );
- bzero( &total, sizeof (TOTAL) );
- return 0;
- }
- lp_bmap( &total.first, 4 );
- wp_bmap( &total.root, 5 );
-
- if( !read_item( &author_cnts, (MEM_SIZE)total.author * sizeof (WORD) )
- || !read_item( &strings, (MEM_SIZE)total.string1 )
- || !read_item( &subject_cnts, (MEM_SIZE)total.subject * sizeof (WORD) )
- || !read_item( &p_roots, (MEM_SIZE)total.root * sizeof (PACKED_ROOT) )
- || !read_item( &p_articles, (MEM_SIZE)total.article * sizeof (PACKED_ARTICLE) ) ) {
- printf( "\n\nRead failed for thread data -- continuing unthreaded.\n" );
- fclose( fp_in );
- unuse_data( 0 );
- return 0;
- }
- fclose( fp_in );
-
- if( !word_same || !long_same ) {
- wp_bmap( author_cnts, total.author );
- wp_bmap( subject_cnts, total.subject );
- for( i = 0; i < total.root; i++ ) {
- lp_bmap( &p_roots[i].root_num, 1 );
- wp_bmap( &p_roots[i].articles, 3 );
- }
- for( i = 0; i < total.article; i++ ) {
- lp_bmap( &p_articles[i].num, 2 );
- wp_bmap( &p_articles[i].subject, 8 );
- }
- }
-
- #ifndef lint
- author_ptrs = (char **)safemalloc( total.author * sizeof (char **) );
- subject_ptrs = (char **)safemalloc( total.subject * sizeof (char **) );
- root_subjects = (WORD *)safemalloc( total.root * sizeof (WORD) );
- root_article_cnts = (WORD *)safemalloc( total.root * sizeof (WORD) );
- #endif
- selected_roots = safemalloc( total.root * sizeof (char) );
-
- bzero( root_article_cnts, total.root * sizeof (WORD) );
- bzero( selected_roots, total.root * sizeof (char) );
-
- for( i = 0, ptr = strings; i < total.author; i++ ) {
- author_ptrs[i] = ptr;
- ptr += strlen( ptr ) + 1;
- }
-
- for( i = 0, j = 0; i < total.root; i++ ) {
- root_subjects[i] = j;
- k = p_roots[i].subject_cnt;
- while( k-- ) {
- root_article_cnts[i] += subject_cnts[j];
- subject_ptrs[j++] = ptr;
- ptr += strlen( ptr ) + 1;
- }
- if( saved_selections ) {
- for( k = 0; k < selected_root_cnt; k++ ) {
- if( p_roots[i].root_num == saved_selections[k] ) {
- selected_roots[i] = 1;
- }
- }
- }
- }
- count_roots( !saved_selections );
- safefree( &saved_selections );
- select_page = 0;
- return 1;
- }
-
- /* A short-hand for reading a chunk of the file into a malloced array.
- */
- static int
- read_item( dest, len )
- char **dest;
- MEM_SIZE len;
- {
- int ret;
-
- *dest = safemalloc( len );
- ret = fread( *dest, 1, (int)len, fp_in );
- if( ret != len ) {
- free( *dest );
- *dest = Nullch;
- return 0;
- }
- return 1;
- }
-
- /* Free some memory if it hasn't already been freed.
- */
- static void
- safefree( pp )
- char **pp;
- {
- if( *pp ) {
- free( *pp );
- *pp = Nullch;
- }
- }
-
- /* Discard the thread data that we received through the use_data() call.
- ** If "save_selections" is non-zero, we'll try to remember which roots
- ** are currently selected long enough for the use_data() call to re-use
- ** them. Only do this when you are going to re-open the same data file
- ** immediately with use_data() (presumably because the data has been
- ** updated while we were using it).
- */
- void
- unuse_data( save_selections )
- bool save_selections;
- {
- int i, j;
-
- if( save_selections ) {
- #ifndef lint
- saved_selections
- = (ART_NUM *)safemalloc( selected_root_cnt * sizeof (ART_NUM) );
- #endif
- for( i = 0, j = 0; i < total.root; i++ ) {
- if( selected_roots[i] && root_article_cnts[i] ) {
- saved_selections[j++] = p_roots[i].root_num;
- }
- }
- } else {
- selected_root_cnt = selected_count = 0;
- }
- safefree( &p_roots );
- safefree( &root_subjects );
- safefree( &author_cnts );
- safefree( &subject_cnts );
- safefree( &author_ptrs );
- safefree( &subject_ptrs );
- safefree( &root_article_cnts );
- safefree( &selected_roots );
- safefree( &p_articles );
- safefree( &strings );
-
- p_art = curr_p_art = Nullart;
- init_tree(); /* free any tree lines */
-
- bzero( &total, sizeof (TOTAL) );
- }
-
- /* Transform each WORD's byte-ordering in a buffer of the designated length.
- */
- static void
- wp_bmap( buf, len )
- WORD *buf;
- int len;
- {
- union {
- BYTE b[sizeof (WORD)];
- WORD w;
- } in, out;
- register int i;
-
- if( word_same ) {
- return;
- }
- while( len-- ) {
- in.w = *buf;
- for( i = 0; i < sizeof (WORD); i++ ) {
- out.b[my_bmap.w[i]] = in.b[mt_bmap.w[i]];
- }
- *buf++ = out.w;
- }
- }
-
- /* Transform each LONG's byte-ordering in a buffer of the designated length.
- */
- static void
- lp_bmap( buf, len )
- LONG *buf;
- int len;
- {
- union {
- BYTE b[sizeof (LONG)];
- LONG l;
- } in, out;
- register int i;
-
- if( long_same ) {
- return;
- }
- while( len-- ) {
- in.l = *buf;
- for( i = 0; i < sizeof (LONG); i++ ) {
- out.b[my_bmap.l[i]] = in.b[mt_bmap.l[i]];
- }
- *buf++ = out.l;
- }
- }
-
- #endif /* USETHREADS */
-