/* Program Name            : FILERAPP.C                                 */
/*   Original Author       : C. K. Hung					*/
/*   Date                  : 22-OCT-1991				*/
/*   Program Description   :                                            */
/*                         :                                            */
/* Revision History follows                                             */
 
 
/* ****  INCLUDE FILES *** */
 
#include "global.h"
#include "dx.h"
#include "filer.h"
#include "filerapp.h"
#include "filerenc.h"
#include "filerque.h"
#include "inquire.h"
#include <signal.h>
 
 
 
/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      tbs
**
**--
**/
int	filer_append()
{
    if (DX_CURRENT_DIRECTORY.filemode == multiple)
	filer_multiple_append();
    else
	filer_single_append();
    return DX__NORMAL;
}
 
 
/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	filer_multiple_append()
{
    char errmsg[MAXFILESPEC+1];
 
    strcpy(errmsg, "Error appending file");
    multi_get_userinput_and_exec(
	filer_append$1,
	"Multiple Append",
	"Append to: ",
	"",
	errmsg);
    return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	filer_single_append()
{
    char errmsg[MAXFILESPEC+1];
    char fn[MAXFILESPEC+1];
 
    if (DX_CURRENT_FILE->fn[ strlen(DX_CURRENT_FILE->fn)-1 ] == ']')
    {
        signal_err("Append to a directory file not allowed", bell);
    }
    else
    {
	find_full_path_name(DX_CURRENT_FILE->fn, fn, cntrl_info_block.cur_win);
	strcpy(errmsg, "Error appending file");
	get_userinput_and_execute(
	    filer_append$1,
	    "Append File",
	    "Append to: ",
	    "",
	    errmsg,
	    fn);
    }
    return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	filer_append$1(to, from, errmsg)
char *to;
char *from;
char *errmsg;
{
    static char linebuf[BUFSIZ+1];
 
    $DESCRIPTOR (linebuf_descriptor, linebuf);
 
    unsigned long retcode;
    char *cp;
    char expand_name[NAM$C_MAXRSS];
 
    struct FAB from_fab;
    struct RAB from_rab;
    struct FAB to_fab;
    struct RAB to_rab;
    struct NAM to_nam;
    struct XABPRO to_xabpro;
    struct XABDAT to_xabdat;
 
    struct fil_dx_tag temp_entry;
    int i;
 
    /*
    **	Initialize Source File FAB
    **/
 
    from_fab = cc$rms_fab;
    from_fab.fab$l_fna = from;
    from_fab.fab$b_fns = strlen(from);
 
    /*
    **	Initialize Source File RAB
    **/
 
    from_rab = cc$rms_rab;
    from_rab.rab$l_fab = &from_fab;
 
    if (sys$open (
	    &from_fab,
	    0,
	    0) != RMS$_NORMAL)
    {
	strcpy(errmsg, "Insufficient privilege for read operation");
	return DX__ERROR;
    }
 
    /*
    **	Initialize Destination File FAB
    **/
 
    to_fab = cc$rms_fab;
    to_nam = cc$rms_nam;
    to_xabpro = cc$rms_xabpro;
    to_xabdat = cc$rms_xabdat;
 
    to_fab.fab$l_fna = to;
    to_fab.fab$b_fns = strlen(to);
    to_fab.fab$b_fac = FAB$M_GET | FAB$M_PUT;
 
    to_fab.fab$l_dna = from;
    to_fab.fab$b_dns = strcspn (from, ";");
 
    to_nam.nam$l_esa = &expand_name;
    to_nam.nam$b_ess = NAM$C_MAXRSS;
 
    to_fab.fab$l_nam = &to_nam;
    to_fab.fab$l_xab = &to_xabpro;
    to_xabpro.xab$l_nxt = &to_xabdat;
 
    /*
    **	Initialize Source File RAB
    **/
 
    to_rab = cc$rms_rab;
    to_rab.rab$l_fab = &to_fab;
 
    if ((retcode = sys$open (
		    &to_fab,
		    0,
		    0)) != RMS$_NORMAL)
    {
	char errmsg1[256];
	$DESCRIPTOR (errmsg1_descrip, errmsg1);
	unsigned short len;
 
        sys$close (
            &from_fab,
            0,
            0);
        lib$sys_getmsg (
            &retcode,
            &len,
            &errmsg1_descrip,
            0,
            0);
	errmsg1[len] = EOS;
	strcpy(errmsg, errmsg1);
	return DX__ERROR;
    }
 
    from_rab.rab$b_rac = RAB$C_SEQ;
    from_rab.rab$l_ubf = linebuf;
    from_rab.rab$w_usz = BUFSIZ;
 
    if ((retcode = sys$connect (
			&from_rab,
			0,
			0)) != RMS$_NORMAL)
    {
	sys$close(&from_fab, 0, 0);
	strcpy(errmsg, "Error connecting to source file");
	return DX__ERROR;
    }
 
    to_rab.rab$l_ubf = linebuf;
    to_rab.rab$w_usz = BUFSIZ;
    to_rab.rab$b_rac = RAB$C_SEQ;
    to_rab.rab$l_rbf = linebuf;
 
    if ((retcode = sys$connect (
			&to_rab,
			0,
			0)) != RMS$_NORMAL)
    {
	sys$close(&from_fab, 0, 0);
	sys$close(&to_fab, 0, 0);
	strcpy(errmsg, "Error connecting to destination file");
	return DX__ERROR;
    }
 
    while ((retcode = sys$get (
                          &to_rab,
                          0,
                          0)) != RMS$_EOF)
    {
        if (retcode != RMS$_NORMAL)
        {
            strcpy(errmsg, "Error positioning to EOF of destination file");
	    sys$close(from_fab, 0, 0);
	    sys$close(to_fab, 0, 0);
	    return DX__ERROR;
        }
    }
 
    while ((retcode = sys$get (
			  &from_rab,
			  0,
			  0)) != RMS$_EOF)
    {
	if (retcode != RMS$_NORMAL)
	{
	    sprintf(errmsg, "Error getting a record from source file");
	    sys$close(from_fab, 0, 0);
	    sys$close(to_fab, 0, 0);
	    return DX__ERROR;
	}
 
	to_rab.rab$w_rsz = from_rab.rab$w_rsz;
	if ((retcode = sys$put (
			&to_rab,
			0,
			0)) != RMS$_NORMAL)
	{
	    sys$close(&from_fab, 0, 0);
	    sys$close(&to_fab, 0, 0);
	    sprintf(errmsg, "Error writing to destination file");
	    return DX__ERROR;
	}
    }
 
    if (sys$close (
	    &from_fab,
	    0,
	    0) != RMS$_NORMAL)
    {
	strcpy(errmsg, "Close source file failed");
	return DX__ERROR;
    }
 
    if (sys$close (
	    &to_fab,
	    0,
	    0) != RMS$_NORMAL)
    {
	strcpy(errmsg, "Close destination file failed");
	return DX__ERROR;
    }
 
    /**  File name  **/
    memcpy(
	temp_entry.fn,
	to_nam.nam$l_name,
	to_nam.nam$b_name+to_nam.nam$b_type+to_nam.nam$b_ver);
    temp_entry.fn[to_nam.nam$b_name+to_nam.nam$b_type+to_nam.nam$b_ver] = EOS;
 
    /**  File id and directory id  **/
    for (i = 0; i <= 2; i++)
    {
	temp_entry.fid[i] = to_nam.nam$w_fid[i];
	temp_entry.did[i] = to_nam.nam$w_did[i];
    }
 
    /**  File size  **/
    temp_entry.filesize = to_fab.fab$l_alq;
 
    /**  File protection  **/
    temp_entry.fpro = to_xabpro.xab$w_pro;
 
    /**  Creation date  **/
    temp_entry.cdat = to_xabdat.xab$q_cdt;
 
    /**  Revision date  **/
    temp_entry.rdat = to_xabdat.xab$q_rdt;
 
    /**  Expiration date  **/
    temp_entry.edat = to_xabdat.xab$q_edt;
 
    /**  Backup date  **/
    temp_entry.bdat = to_xabdat.xab$q_bdt;
 
    /*
    **	Update filer cache
    **/
 
    if (update_filer_cache(
	    temp_entry, change_to_filer_cache, errmsg) == DX__ERROR)
    {
        signal_err(errmsg, bell);
    }
 
    /*
    **	Update filer displays
    **/
 
    if (change_to_filer(temp_entry, errmsg, cntrl_info_block.cur_win)
	== DX__ERROR)
    {
        return DX__ERROR;
    }
 
    for (i = 0;  i < cntrl_info_block.windows;  i++)
    {
    	if (i != cntrl_info_block.cur_win)
	{
	    if (change_to_filer(temp_entry, errmsg, i) == DX__ERROR)
	    {
	    	 return DX__ERROR;
	    }
	}
    }
 
    return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	change_to_filer(
		struct fil_dx_tag e,
		char *errmsg,
		unsigned short int win)
{
    struct fil_dx_tag *p, *q;
    char str[MAXFILESPEC+1];
    $DESCRIPTOR (str_descrip, str);
 
    /*
    **	Update current display.
    **	Find file location in current display.
    **/
 
    for (p = cntrl_info_block.dir_dx[win].dir_filelist->forward;
	 p != cntrl_info_block.dir_dx[win].non_dir_filelist; p = p->forward)
    {
        if (p == cntrl_info_block.dir_dx[win].dir_filelist)
        {
            p = cntrl_info_block.dir_dx[win].non_dir_filelist;
        }
	else
	{
	    if (e.fid[0] == p->fid[0] &&
		e.fid[1] == p->fid[1] &&
		e.fid[2] == p->fid[2])
	    {
		break;
	    }
	}
    }
 
    if (p == cntrl_info_block.dir_dx[win].non_dir_filelist)
    {	    /**  Modified file not in this display  **/
	return DX__NORMAL;
    }
 
    cntrl_info_block.dir_dx[win].tot_blocks += e.filesize - p->filesize;
    p->filesize = e.filesize;
 
    format_filer_entry(p, str, win);
 
    LENGTH(str_descrip) = strlen(str);
    check_OK(smg$put_chars (
		&cntrl_info_block.dir_dx[win].filer_display.id,
		&str_descrip,
		&p->beg_y,
		&p->beg_x,
		0,
		0,
		0,
		0))
 
    put_filer_stat(win);
 
    return DX__NORMAL;
}
