home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / CODE4-1.ZIP / SOURCE.ZIP / M4WRITE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-13  |  8.5 KB  |  328 lines

  1.  
  2. /* m4write.c   (c)Copyright Sequiter Software Inc., 1987, 1988, 1989.  All rights reserved. */
  3.  
  4. #include "d4base.h"
  5. #include "u4error.h"
  6. #include "m4.h"
  7.  
  8. #ifndef UNIX
  9.    #include <fcntl.h>
  10.    #include <io.h>  
  11.    #include <process.h>
  12. #endif
  13. #include <string.h>
  14. #include <stdlib.h>
  15.  
  16. extern  int  m4to_disk( FREE_AREA *, M *) ;
  17. extern  int  m4skip_area( M *) ;
  18.  
  19. extern  long m4write_do( M *, long, char *, int ) ;
  20.  
  21. extern  BASE *v4base ;
  22.  
  23. m4to_disk( free_area_ptr, m_ptr )
  24. FREE_AREA  *free_area_ptr ;
  25. M      *m_ptr ;
  26. {
  27.    int  rc ;
  28.  
  29.    if ( free_area_ptr->to_disk )
  30.    {
  31.       free_area_ptr->to_disk =  0 ;
  32.  
  33.       if ( free_area_ptr->num < 0xFFFFFL )
  34.       {
  35.      /* Not at end of file */
  36.      lseek( m_ptr->hand, free_area_ptr->block_no * m_ptr->block_size, 0 ) ;
  37.      rc =  write( m_ptr->hand, (char *) free_area_ptr, CHAIN_SIZE ) ;
  38.      if ( rc != CHAIN_SIZE )
  39.      {
  40.         u4error( E_WRITE, "Memo File:", m4name( m_ptr->base_ref), (char *) 0 ) ;
  41.         return -1 ;
  42.      }
  43.       }
  44.    }
  45.    return 0 ;
  46. }
  47.  
  48. /*  m4skip_area returns:  1 - Write Done;  0 - Continue;  -1 - Error */
  49.  
  50. m4skip_area( m_ptr )
  51. M *m_ptr ;   /* Memo Write Status Information Pointer */
  52. {
  53.    int  rc ;
  54.  
  55.    if ( m4to_disk( &m_ptr->prev, m_ptr ) < 0 )  return -1 ;
  56.  
  57.    if ( m_ptr->write_done && m_ptr->free_done )
  58.    {
  59.       if ( m4to_disk( &m_ptr->cur, m_ptr ) < 0 )  return -1 ;
  60.       return 1 ;
  61.    }
  62.  
  63.    memcpy( (char *) &m_ptr->prev, (char *) &m_ptr->cur, sizeof(FREE_AREA) ) ;
  64.    m_ptr->cur.block_no =  m_ptr->cur.next ;
  65.    m_ptr->cur.to_disk  =  0 ;
  66.  
  67.    lseek( m_ptr->hand, m_ptr->block_size * m_ptr->cur.block_no, 0 ) ;
  68.    rc = read( m_ptr->hand, (char *) &m_ptr->cur, CHAIN_SIZE ) ;
  69.    if ( rc < 0 )
  70.    {
  71.       u4error( E_READ, "Reading Memo File:", m4name(m_ptr->base_ref), (char *) 0 ) ;
  72.       return -1 ;
  73.    }
  74.    if ( rc < CHAIN_SIZE )
  75.       m_ptr->cur.num =  0xFFFFFFFL ;   /* Unlimited number at the end of the memo file */
  76.  
  77.    return 0 ;
  78. }
  79.  
  80. long  m4write_do( m_ptr, free_block, str, str_len )
  81. M    *m_ptr ;
  82. long  free_block ;    /* The block number to be freed */
  83. char *str ;
  84. int   str_len ;
  85. {
  86.    MEMO_BLOCK   write_block ;  /* The Header Information on what is to be written */
  87.    int      no_to_write ;  /* The number of blocks to write */
  88.    long     write_block_no ; /* The actual block number which was written */
  89.  
  90.    MEMO_BLOCK   read_block ;   /* The header information on the block to be freed */
  91.    int      no_to_free ;   /* The number of blocks to free */
  92.    int      rc ;
  93.  
  94.    write_block.minus_one =  -1 ;
  95.    write_block.start_pos =  sizeof(MEMO_BLOCK) ;
  96.    write_block.num_chars =  str_len + sizeof(MEMO_BLOCK) ;
  97.    no_to_write    =  (int) ((write_block.num_chars + m_ptr->block_size -1) / m_ptr->block_size) ;
  98.    write_block_no =  0L ;
  99.  
  100.    if ( str_len == 0 )
  101.    {
  102.       no_to_write =  0 ;
  103.       m_ptr->write_done =  1 ;
  104.    }
  105.  
  106.    if ( free_block <= 0L )
  107.       m_ptr->free_done =  1 ;
  108.    else
  109.    {
  110.       /* Read the Memo Block to be freed and find out how many blocks to free */
  111.       lseek( m_ptr->hand, m_ptr->block_size * free_block, 0 ) ;
  112.       rc =  read( m_ptr->hand, (char *) &read_block, (unsigned int) sizeof(read_block)) ;
  113.       if ( rc <  (int) sizeof(read_block))
  114.       {
  115.      u4error( E_READ, "Reading Memo File:", m4name(m_ptr->base_ref), (char *) 0 ) ;
  116.      return -1L ;
  117.       }
  118.  
  119.       if ( read_block.minus_one == -1 )
  120.      no_to_free =  (int) ((read_block.num_chars + m_ptr->block_size -1) /
  121.               m_ptr->block_size) ;
  122.       else
  123.      no_to_free =  1 ;  /* dBASE III Block */
  124.    }
  125.  
  126.    /* Skip through the free chain; 
  127.       Add the free blocks at the appropriate point.
  128.       Write the new blocks as soon as a large enough area is located.
  129.    */
  130.  
  131.    for( rc = m4skip_area(m_ptr); rc == 0; rc = m4skip_area(m_ptr) )
  132.    {
  133.       /* Check to see if an area needs to be freed */
  134.       if ( m_ptr->cur.next > free_block  &&  ! m_ptr->free_done )
  135.       {
  136.      if ( m4to_disk( &m_ptr->prev, m_ptr ) < 0 )  return -1L ;
  137.      memcpy( (char *) &m_ptr->prev, (char *) &m_ptr->cur, sizeof(FREE_AREA) ) ;
  138.  
  139.      m_ptr->cur.next     =  m_ptr->prev.next ;
  140.      m_ptr->cur.num      =  no_to_free ;
  141.      m_ptr->cur.to_disk  =  1 ;
  142.      m_ptr->cur.block_no =  free_block ;
  143.  
  144.      m_ptr->prev.next    =  free_block ;
  145.      m_ptr->prev.to_disk =  1 ;
  146.  
  147.      m_ptr->free_done =  1 ;
  148.       }
  149.  
  150.       /* Check to see if the string information can be written in the current area */
  151.       if ( m_ptr->cur.num >= no_to_write  &&  ! m_ptr->write_done )
  152.       {
  153.      write_block_no =  m_ptr->cur.block_no ;
  154.  
  155.      /* First write the data */
  156.      lseek( m_ptr->hand, m_ptr->block_size * m_ptr->cur.block_no, 0 ) ;
  157.      if ( write(m_ptr->hand, (char *) &write_block, 
  158.         (unsigned int) sizeof(write_block)) != (int) sizeof(write_block) )
  159.      {
  160.         u4error( E_WRITE, "Memo File:", m4name(m_ptr->base_ref), (char *) 0 ) ;
  161.         return -1L ;
  162.      }
  163.      if ( write(m_ptr->hand, str, (unsigned int) str_len) != str_len )
  164.      {
  165.         u4error( E_WRITE, "Memo File:", m4name(m_ptr->base_ref), (char *) 0 ) ;
  166.         return -1L ;
  167.      }
  168.  
  169.      /* Now Fix the Chains */
  170.      if ( m_ptr->cur.num ==  no_to_write )
  171.      {
  172.         /* Complete Chain Used */
  173.         m_ptr->prev.next =  m_ptr->cur.next ;
  174.         memcpy( (char *) &m_ptr->cur, (char *) &m_ptr->prev, sizeof(FREE_AREA)) ;
  175.         m_ptr->prev.to_disk =  0 ;
  176.         m_ptr->cur.to_disk  =  1 ;
  177.      }
  178.      else
  179.      {
  180.         /* Only part of the free space was used */
  181.         m_ptr->cur.num      -=  no_to_write ;
  182.         m_ptr->cur.to_disk   =  1 ;
  183.         m_ptr->cur.block_no +=  no_to_write ;
  184.  
  185.         m_ptr->prev.next     =  m_ptr->cur.block_no ;
  186.         m_ptr->prev.to_disk  =  1 ;
  187.      }
  188.  
  189.      m_ptr->write_done =  1 ;
  190.       }
  191.    }
  192.    if ( rc < 0 )  return -1L ;
  193.  
  194.    return  write_block_no ;
  195. }
  196.  
  197. m4write( field_ref, rec_num, str, str_len )
  198. long  field_ref, rec_num ;
  199. char *str ;
  200. int   str_len ;
  201. {
  202.    M    m ;
  203.    int  old_base, rc ;
  204.    long free_block, new_block ;
  205.  
  206.    if ( str_len < 0 )
  207.       str_len =  0 ;
  208.  
  209.    memset( (char *) &m, 0, sizeof(m) ) ;
  210.    m.base_ref =  (int) (field_ref >> 16) ;
  211.  
  212.    old_base =  d4select( m.base_ref ) ;
  213.    if ( rec_num > d4reccount() ) 
  214.    {
  215.       d4go( 0L ) ;
  216.       rc =  0 ;
  217.    }
  218.    else
  219.       rc =  d4go(rec_num) ;
  220.  
  221.    d4select(old_base) ;
  222.    if ( rc < 0 )  return -1 ;
  223.  
  224.    if ( m4open(m.base_ref) < 0 )   return -1 ;
  225.  
  226.    m.block_size =  v4base[m.base_ref].memo_size ;
  227.    m.hand       =  v4base[m.base_ref].memo_file ;
  228.  
  229.    free_block =   c4atol( f4ptr(field_ref),  f4width(field_ref) ) ;
  230.  
  231.    if ( u4lock(m.hand, 0L, 0x7FFFFFFFL, 1) < 0 )  return -1 ;
  232.    new_block =  m4write_do( &m, free_block, str, str_len ) ;
  233.    if ( u4unlock( m.hand, 0L, 0x7FFFFFFFL ) < 0)  return -1 ;
  234.    if ( new_block < 0L )  return -1 ;
  235.  
  236.    if ( new_block == 0L ) 
  237.       memset( f4ptr(field_ref), (int) ' ', f4width(field_ref) ) ;
  238.    else
  239.       c4ltoa( new_block, f4ptr(field_ref), -f4width(field_ref) ) ;
  240.  
  241.    if ( d4write( rec_num ) < 0 )  return -1 ;
  242.  
  243.    return( str_len ) ;
  244. }
  245.  
  246. #ifndef UNIX
  247. m4edit( field_ref, rec_num, editor_name, max_size ) 
  248. long  field_ref, rec_num ;
  249. char *editor_name ;
  250. int   max_size ;
  251. {
  252.    char *ptr ;
  253.    int   hand, num_read ;
  254.    char  memoedit_ptr[14] ;
  255.  
  256.    strcpy( memoedit_ptr, "MEMOXXXX" ) ;
  257.    mktemp( memoedit_ptr ) ;
  258.  
  259.    if ( max_size <= 0 )  return -1 ;
  260.  
  261.    ptr =  malloc( max_size ) ;
  262.    if ( ptr == (char *) 0 )   return 1 ;
  263.  
  264.    if ((num_read = m4read( field_ref, rec_num, ptr, max_size))  < 0 ) 
  265.    {
  266.       h4free_memory(ptr) ;
  267.       return -1 ;
  268.    }
  269.  
  270.    if ( (hand = u4open(memoedit_ptr,2)) < 0 )  
  271.    {
  272.       h4free_memory(ptr) ;
  273.       return -1 ;
  274.    }
  275.  
  276.    lseek( hand, 0L, 0 ) ;
  277.    if ( write( hand, ptr, num_read ) != num_read ) 
  278.    {
  279.       h4free_memory(ptr) ;
  280.       close(hand) ;
  281.       u4error( E_WRITE, memoedit_ptr, (char *) 0 ) ;
  282.       return -1 ;
  283.    }
  284.  
  285.    close( hand ) ;
  286.  
  287.    if ( spawnl( P_WAIT, editor_name, "", memoedit_ptr, (char *) 0 )  < 0)
  288.    {
  289.       h4free_memory(ptr) ;
  290.       close(hand) ;
  291.       u4error( E_EDITOR, editor_name, (char *) 0 ) ;
  292.       return -1 ;
  293.    }
  294.  
  295.    if ( (hand = u4open(memoedit_ptr,0)) < 0 )  
  296.    {
  297.       h4free_memory(ptr) ;
  298.       return -1 ;
  299.    }
  300.  
  301.    lseek( hand, 0L, 0 ) ;
  302.    if ( (num_read = read(hand, ptr, max_size)) < 0 ) 
  303.    {
  304.       h4free_memory(ptr) ;
  305.       close(hand) ;
  306.       u4error( E_READ, memoedit_ptr, (char *) 0 ) ;
  307.       return -1 ;
  308.    }
  309.  
  310.    close(hand) ;
  311.  
  312.    #ifdef TURBO
  313.       unlink( memoedit_ptr ) ;
  314.    #else
  315.       remove( memoedit_ptr ) ;
  316.    #endif
  317.  
  318.    if ( m4write(field_ref, rec_num, ptr, num_read) < 0 )
  319.    {
  320.       h4free_memory(ptr) ;
  321.       return -1 ;
  322.    }
  323.  
  324.    h4free_memory( ptr ) ;
  325.    return 0 ;
  326. }
  327. #endif
  328.