home *** CD-ROM | disk | FTP | other *** search
-
- /* m4write.c (c)Copyright Sequiter Software Inc., 1987-1990. All rights reserved. */
-
- #include "p4misc.h"
- #include "d4all.h"
- #include "u4error.h"
- #include "m4.h"
-
- #include <string.h>
-
- #ifndef UNIX
- #include <process.h>
- #include <io.h>
- #endif
-
- #ifdef __WATCOMC__
- #include <stdio.h>
- #endif
-
- extern int m4to_disk( FREE_AREA *, M *) ;
- extern int m4skip_area( M *) ;
- extern int v4lock_wait ;
-
- extern long m4write_do( M *, long, char *, int ) ;
-
- extern BASE *v4base ;
-
- m4to_disk( FREE_AREA *free_area_ptr, M *m_ptr )
- {
- int rc ;
-
- if ( free_area_ptr->to_disk )
- {
- free_area_ptr->to_disk = 0 ;
-
- if ( free_area_ptr->num < 0xFFFFFL )
- {
- /* Not at end of file */
- lseek( m_ptr->hand, free_area_ptr->block_no * m_ptr->block_size, 0 ) ;
- rc = write( m_ptr->hand, (char *) free_area_ptr, CHAIN_SIZE ) ;
- if ( rc != CHAIN_SIZE )
- {
- u4error( E_WRITE, "Memo File:", m4name( m_ptr->base_ref), (char *) 0 ) ;
- return -1 ;
- }
- }
- }
- return 0 ;
- }
-
- /* m4skip_area returns: 1 - Write Done; 0 - Continue; -1 - Error
-
- m_ptr - Memo Write Status Information Pointer
- */
-
- m4skip_area( M *m_ptr )
- {
- int rc ;
-
- if ( m4to_disk( &m_ptr->prev, m_ptr ) < 0 ) return -1 ;
-
- if ( m_ptr->write_done && m_ptr->free_done )
- {
- if ( m4to_disk( &m_ptr->cur, m_ptr ) < 0 ) return -1 ;
- return 1 ;
- }
-
- memcpy( (char *) &m_ptr->prev, (char *) &m_ptr->cur, sizeof(FREE_AREA) ) ;
- m_ptr->cur.block_no = m_ptr->cur.next ;
- m_ptr->cur.to_disk = 0 ;
-
- lseek( m_ptr->hand, m_ptr->block_size * m_ptr->cur.block_no, 0 ) ;
- rc = read( m_ptr->hand, (char *) &m_ptr->cur, CHAIN_SIZE ) ;
- if ( rc < 0 )
- {
- u4error( E_READ, "Reading Memo File:", m4name(m_ptr->base_ref), (char *) 0 ) ;
- return -1 ;
- }
- if ( rc < CHAIN_SIZE )
- m_ptr->cur.num = 0xFFFFFFFL ; /* Unlimited number at the end of the memo file */
-
- return 0 ;
- }
-
- long m4write_do( M *m_ptr, long free_block, char *str, int str_len )
- {
- MEMO_BLOCK write_block ; /* The Header Information on what is to be written */
- int no_to_write ; /* The number of blocks to write */
- long write_block_no ; /* The actual block number which was written */
-
- MEMO_BLOCK read_block ; /* The header information on the block to be freed */
- int no_to_free ; /* The number of blocks to free */
- int rc ;
-
- write_block.minus_one = -1 ;
- write_block.start_pos = sizeof(MEMO_BLOCK) ;
- write_block.num_chars = str_len + sizeof(MEMO_BLOCK) ;
- no_to_write = (int) ((write_block.num_chars + m_ptr->block_size -1) / m_ptr->block_size) ;
- write_block_no = 0L ;
-
- if ( str_len == 0 )
- {
- no_to_write = 0 ;
- m_ptr->write_done = 1 ;
- }
-
- if ( free_block <= 0L )
- m_ptr->free_done = 1 ;
- else
- {
- /* Read the Memo Block to be freed and find out how many blocks to free */
- lseek( m_ptr->hand, m_ptr->block_size * free_block, 0 ) ;
- rc = read( m_ptr->hand, (char *) &read_block, (unsigned int) sizeof(read_block)) ;
- if ( rc < (int) sizeof(read_block))
- {
- u4error( E_READ, "Reading Memo File:", m4name(m_ptr->base_ref), (char *) 0 ) ;
- return -1L ;
- }
-
- if ( read_block.minus_one == -1 )
- no_to_free = (int) ((read_block.num_chars + m_ptr->block_size -1) /
- m_ptr->block_size) ;
- else
- no_to_free = 1 ; /* dBASE III Block */
- }
-
- /* Skip through the free chain;
- Add the free blocks at the appropriate point.
- Write the new blocks as soon as a large enough area is located.
- */
-
- for( rc = m4skip_area(m_ptr); rc == 0; rc = m4skip_area(m_ptr) )
- {
- /* Check to see if an area needs to be freed */
- if ( m_ptr->cur.next > free_block && ! m_ptr->free_done )
- {
- if ( m4to_disk( &m_ptr->prev, m_ptr ) < 0 ) return -1L ;
- memcpy( (char *) &m_ptr->prev, (char *) &m_ptr->cur, sizeof(FREE_AREA) ) ;
-
- m_ptr->cur.next = m_ptr->prev.next ;
- m_ptr->cur.num = no_to_free ;
- m_ptr->cur.to_disk = 1 ;
- m_ptr->cur.block_no = free_block ;
-
- m_ptr->prev.next = free_block ;
- m_ptr->prev.to_disk = 1 ;
-
- m_ptr->free_done = 1 ;
- }
-
- /* Check to see if the string information can be written in the current area */
- if ( m_ptr->cur.num >= no_to_write && ! m_ptr->write_done )
- {
- write_block_no = m_ptr->cur.block_no ;
-
- /* First write the data */
- lseek( m_ptr->hand, m_ptr->block_size * m_ptr->cur.block_no, 0 ) ;
- if ( write(m_ptr->hand, (char *) &write_block,
- (unsigned int) sizeof(write_block)) != (int) sizeof(write_block) )
- {
- u4error( E_WRITE, "Memo File:", m4name(m_ptr->base_ref), (char *) 0 ) ;
- return -1L ;
- }
- if ( write(m_ptr->hand, str, (unsigned int) str_len) != str_len )
- {
- u4error( E_WRITE, "Memo File:", m4name(m_ptr->base_ref), (char *) 0 ) ;
- return -1L ;
- }
-
- /* Now Fix the Chains */
- if ( m_ptr->cur.num == no_to_write )
- {
- /* Complete Chain Used */
- m_ptr->prev.next = m_ptr->cur.next ;
- memcpy( (char *) &m_ptr->cur, (char *) &m_ptr->prev, sizeof(FREE_AREA)) ;
- m_ptr->prev.to_disk = 0 ;
- m_ptr->cur.to_disk = 1 ;
- }
- else
- {
- /* Only part of the free space was used */
- m_ptr->cur.num -= no_to_write ;
- m_ptr->cur.to_disk = 1 ;
- m_ptr->cur.block_no += no_to_write ;
-
- m_ptr->prev.next = m_ptr->cur.block_no ;
- m_ptr->prev.to_disk = 1 ;
- }
-
- m_ptr->write_done = 1 ;
- }
- }
- if ( rc < 0 ) return -1L ;
-
- return write_block_no ;
- }
-
- m4write( long field_ref, long rec_num, char *str, int str_len )
- {
- M m ;
- int old_base, rc ;
- long free_block, new_block ;
-
- if ( str_len < 0 )
- str_len = 0 ;
-
- memset( (char *) &m, 0, sizeof(m) ) ;
- m.base_ref = (int) (field_ref >> 16) ;
-
- if ( rec_num > d4reccount() )
- d4blank() ;
- else
- {
- old_base = d4select( m.base_ref ) ;
- rc = d4go(rec_num) ;
- d4select(old_base) ;
- if ( rc < 0 ) return rc ;
- }
-
- if ( m4open(m.base_ref) < 0 ) return -1 ;
-
- m.block_size = v4base[m.base_ref].memo_size ;
- m.hand = v4base[m.base_ref].memo_file ;
-
- free_block = c4atol( f4ptr(field_ref), f4width(field_ref) ) ;
-
- rc = u4lock(m.hand, 0L, 0x7FFFFFFFL, v4lock_wait) ;
- if ( rc < 0 ) return rc ;
- new_block = m4write_do( &m, free_block, str, str_len ) ;
- if ( u4unlock( m.hand, 0L, 0x7FFFFFFFL ) < 0) return -1 ;
- if ( new_block < 0L ) return -1 ;
-
- if ( new_block == 0L )
- memset( f4ptr(field_ref), (int) ' ', (size_t) f4width(field_ref) ) ;
- else
- c4ltoa( new_block, f4ptr(field_ref), -f4width(field_ref) ) ;
-
- old_base = d4select( m.base_ref ) ;
- if ( rec_num > d4reccount() )
- rc = d4append() ;
- else
- rc = d4write( rec_num ) ;
- d4select(old_base) ;
- if ( rc < 0 ) return -1 ;
-
- return( str_len ) ;
- }
-
- m4edit( long field_ref, long rec_num, char *editor_name, int max_size )
- {
- #ifndef NO_SPAWNL
- char *ptr ;
- int hand, num_read ;
- char memoedit_ptr[14] ;
-
- if ( max_size <= 0 ) return -1 ;
-
- ptr = h4alloc( max_size ) ;
- if ( ptr == (char *) 0 ) return 1 ;
-
- if ((num_read = m4read( field_ref, rec_num, ptr, max_size)) < 0 )
- {
- h4free_memory(ptr) ;
- return -1 ;
- }
-
- strcpy( memoedit_ptr, "M4" ) ;
- if ( (hand = u4temp_create(memoedit_ptr)) < 0 )
- {
- h4free_memory(ptr) ;
- return -1 ;
- }
-
- lseek( hand, 0L, 0 ) ;
- if ( write( hand, ptr, num_read ) != num_read )
- {
- h4free_memory(ptr) ;
- close(hand) ;
- u4error( E_WRITE, memoedit_ptr, (char *) 0 ) ;
- return -1 ;
- }
-
- close( hand ) ;
-
- if ( spawnl( P_WAIT, editor_name, "", memoedit_ptr, (char *) 0 ) < 0)
- {
- h4free_memory(ptr) ;
- close(hand) ;
- u4error( E_EDITOR, editor_name, (char *) 0 ) ;
- return -1 ;
- }
-
- if ( (hand = u4open(memoedit_ptr,0)) < 0 )
- {
- h4free_memory(ptr) ;
- return -1 ;
- }
-
- lseek( hand, 0L, 0 ) ;
- if ( (num_read = read(hand, ptr, max_size)) < 0 )
- {
- h4free_memory(ptr) ;
- close(hand) ;
- u4error( E_READ, memoedit_ptr, (char *) 0 ) ;
- return -1 ;
- }
-
- close(hand) ;
-
- u4remove( memoedit_ptr ) ;
-
- if ( m4write(field_ref, rec_num, ptr, num_read) < 0 )
- {
- h4free_memory(ptr) ;
- return -1 ;
- }
-
- h4free_memory( ptr ) ;
- #endif
- return 0 ;
- }
-