/* Program Name            : FILERCPY.C                                 */
/*   Original Author       :  C. K. Hung				*/
/*   Date                  : 22-MAY-1991				*/
/*   Program Description   :                                            */
/*                         :                                            */
/* Revision History follows                                             */
 
 
#include "global.h"
#include "dx.h"
#include "filer.h"
#include "filercpy.h"
#include "filerflt.h"
#include "filerkpd.h"
#include "filerque.h"
#include "findfile.h"
#include "inquire.h"
#include <atrdef.h>
#include <iodef.h>
#include <limits.h>
#include <sbkdef.h>
#include <fibdef.h>
 
 
/* ****  INTERNAL FUNCTION PROTOTYPING *** */
static int		    filer_copy$2(char *, char *, char *);
 
 
 
/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      tbs
**
**--
**/
int	filer_copy()
{
    if (DX_CURRENT_DIRECTORY.filemode == multiple)
	filer_multiple_copy();
    else
	filer_single_copy();
    return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	filer_multiple_copy()
{
    char errmsg[MAXFILESPEC+1];
 
    strcpy(errmsg, "Error copying file");
    multi_get_userinput_and_exec(
	filer_copy$1,
	"Multiple Copy",
	"Copy to: ",
	"",
	errmsg);
    return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int filer_single_copy()
{
    char errmsg[MAXFILESPEC+1];
    char fn[MAXFILESPEC+1];
 
    if (!strcmp(DX_CURRENT_FILE->fn, "[-]"))
    {
        signal_err("Copy a parent directory file not allowed", bell);
    }
    else
    {
	find_full_path_name(DX_CURRENT_FILE->fn, fn, cntrl_info_block.cur_win);
	strcpy(errmsg, "Error copying file");
	get_userinput_and_execute(
	    filer_copy$1,
	    "Copy File",
	    "Copy to: ",
	    "",
	    errmsg,
	    fn);
    }
    return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	filer_copy$1(to, from, errmsg)
char *to;
char *from;
char *errmsg;
{
    return filer_copy$2(from, to, errmsg);
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
static int	filer_copy$2(from, to, errmsg)
char *from;
char *to;
char *errmsg;
{
    struct filespec_list_tag *s;
    unsigned short int chan;
    unsigned short chan_o;		    /**  I/O channel		     **/
 
    /**  File Characteristics Bits  **/
    unsigned long fch;
 
    /**  Record Attributes Area  **/
    struct {
	unsigned char fat$b_rtype;
	unsigned char fat$b_rattrib;
	unsigned short int fat$w_rsize;
	struct {
	    unsigned short int fat$w_hiblkh;
	    unsigned short int fat$w_hiblkl;
	} fat$l_hiblk;
	struct {
	    unsigned short int fat$w_efblkh;
	    unsigned short int fat$w_efblkl;
	} fat$l_efblk;
	short int fat$w_ffbyte;
	unsigned char fat$b_bktsize;
	unsigned char fat$b_vfcsize;
	short int fat$w_maxrec;
	short int fat$w_defext;
	short int fat$w_gbc;
	short int spares1;
	int spares2;
	short int spares3;
	short int fat$w_versions;
    } raa;
 
    /**  Statistics Block  **/
    struct sbkdef asb;
 
    /*
    **  struct representing a 64-bit binary value expressing
    **  the date and time
    **/
    DATE_TIME edt,
	      cdt;
    unsigned short int fpro;		    /**  File Protection	     **/
 
    /**  Access Control Block  **/
    struct {
	unsigned short w_size;
	unsigned short w_type;
	char *l_addr;
    } acb[] = {
	{ ATR$S_UCHAR, ATR$C_UCHAR, &fch },
	{ ATR$S_RECATTR, ATR$C_RECATTR, &raa },
	{ ATR$S_STATBLK, ATR$C_STATBLK, &asb },
	{ ATR$S_EXPDATE, ATR$C_EXPDATE, &edt },
	{ ATR$S_CREDATE, ATR$C_CREDATE, (char *)&cdt },
	{ ATR$S_FPRO, ATR$C_FPRO, (char *)&fpro },
	{ 0, 0, (char *)NULL }
    };
 
    struct {
	unsigned short status;
	unsigned short bytcnt;
	int filler;
    } iosb;
 
    unsigned short bytes;
    unsigned long status;
 
    static struct fibdef fib;
    $DESCRIPTOR(fib_descriptor, (char *)&fib);
 
    char filespec[MAXFILESPEC+1];
    unsigned short filespec_length;
    $DESCRIPTOR (filespec_descriptor, filespec);
 
    char buf[BUFSIZ];
    int svb;
 
    struct FAB to_fab;
    struct NAM to_nam;
    char expand_name[NAM$C_MAXRSS];
    char resultant_name[MAXFILESPEC+1];
    $DESCRIPTOR (resultant_name_descriptor, resultant_name);
    unsigned short len;
    char devname[MAXVMSDEVICE+1];
    $DESCRIPTOR(devname_descriptor, devname);
    char *cp;
    unsigned short from_fid[3];
    short status_flag;
    int i;
    struct fil_dx_tag temp_entry;
    char errmsg1[256];
    $DESCRIPTOR (errmsg1_descrip, errmsg1);
 
    /**  Get directory fid and file name of the output file  **/
    to_fab = cc$rms_fab;
    to_nam = cc$rms_nam;
 
    to_fab.fab$l_fna = to;
    to_fab.fab$b_fns = strlen(to);
    to_fab.fab$l_nam = &to_nam;
 
    to_fab.fab$l_dna = from;
    to_fab.fab$b_dns = strlen(from);
 
    to_nam.nam$l_esa = &expand_name;
    to_nam.nam$b_ess = NAM$C_MAXRSS;
 
    if ((status = sys$parse(&to_fab, 0, 0)) != RMS$_NORMAL)
    {
	lib$sys_getmsg (
	    &status,
	    &len,
	    &errmsg1_descrip,
	    0,
	    0);
	errmsg1[len] = EOS;
	strcpy(errmsg, errmsg1);
	return DX__ERROR;
    }
 
    /**  Get a channel for the output file  **/
    strncpy(devname, to_nam.nam$l_dev, to_nam.nam$b_dev);
    devname[to_nam.nam$b_dev] = EOS;
    if ((chan_o = get_chan(devname)) == 0)
    {
	sprintf(errmsg, "Establish a logical link with %s failed", to);
	return DX__ERROR;
    }
 
 
    /**  Directory fid for the input file  **/
    __FIB(fib,fib$r_did_overlay,fib$w_did[0]) = DX_CURRENT_FILE->did[0];
    __FIB(fib,fib$r_did_overlay,fib$w_did[1]) = DX_CURRENT_FILE->did[1];
    __FIB(fib,fib$r_did_overlay,fib$w_did[2]) = DX_CURRENT_FILE->did[2];
 
    /**  SYS$QIO will not use device and directory name  **/
    if ((cp = strchr(from, ']')) == 0)
    {
	strcpy(filespec, from);
    }
    else
    {
	cp++;
	strcpy(filespec, cp);
    }
    LENGTH(filespec_descriptor) = strlen(filespec);
 
    /*
    **	Find the I/O channel for this file
    **/
    for (s = DX_CURRENT_DIRECTORY.cur_filter.name_filespec_list;
	    s != (struct filespec_list_tag *)NULL;  s = s->next)
    {
	struct w_dids_tag *t;
 
        for (t = s->w_dids;  t != (struct w_dids_tag *)NULL;  t = t->next)
        {
	    if (t->did[0] == DX_CURRENT_FILE->did[0] &&
		t->did[1] == DX_CURRENT_FILE->did[1] &&
		t->did[2] == DX_CURRENT_FILE->did[2])
	    {
		chan = t->chan;
		break;
	    }
        }
    }
 
    __FIB(fib,fib$r_acctl_overlay,fib$l_acctl) = 0;
    LENGTH(fib_descriptor) = sizeof (struct fibdef);
    status = sys$qiow (		/**  Read input file attributes  **/
		 0,
		 chan,
		 IO$_ACCESS+IO$M_ACCESS,
		 &iosb,
		 0,
		 0,
		 &fib_descriptor,
		 &filespec_descriptor,
		 0,
		 0,
		 acb,
		 0);
 
    if (!(status &1))
    {	/**  No READ access  **/
	lib$sys_getmsg (
	    &status,
	    &len,
	    &errmsg1_descrip,
	    0,
	    0);
	errmsg1[len] = EOS;
	strcpy(errmsg, errmsg1);
    	return DX__ERROR;
    }
    else if (!(iosb.status & 1))
    {	/**  No READ access  **/
	lib$sys_getmsg (
	    &iosb.status,
	    &len,
	    &errmsg1_descrip,
	    0,
	    0);
	errmsg1[len] = EOS;
	strcpy(errmsg, errmsg1);
    	return DX__ERROR;
    }
    else
    {
	/*
	**  Got input file attributes.
	**  Create a output file use the same attributes.
	**/
 
	/**  Save input file fid  **/
	for (i = 0; i <= 2; i++)
	    from_fid[i] = __FIB(fib,fib$r_fid_overlay,fib$w_fid[i]);
 
	__FIB(fib,fib$r_did_overlay,fib$w_did[0]) = to_nam.nam$w_did[0];
	__FIB(fib,fib$r_did_overlay,fib$w_did[1]) = to_nam.nam$w_did[1];
	__FIB(fib,fib$r_did_overlay,fib$w_did[2]) = to_nam.nam$w_did[2];
 
        memset (filespec, EOS, sizeof filespec);
	strncpy(filespec, to_nam.nam$l_name, to_nam.nam$b_name);
	strncat(filespec, to_nam.nam$l_type, to_nam.nam$b_type);
	if (strchr(to, ';') != 0)
	    strncat(filespec, to_nam.nam$l_ver, to_nam.nam$b_ver);
	else
	    strcat(filespec, ";0");
 
	LENGTH(filespec_descriptor) = strlen(filespec);
 
	/**  Update FIB information for output file  **/
	__FIB(fib,fib$r_acctl_overlay.fib$r_acctl_bits0,fib$v_write) = 1;
	__FIB(fib,fib$r_exctl_overlay.fib$r_exctl_bits,fib$v_extend) = 1;
	fib.fib$l_exsz = (asb.sbk$w_filesizh << 16)+asb.sbk$w_filesizl;
 
	sys$qiow (	/**  Create the output file  **/
	     0,
	     chan_o,
	     IO$_CREATE+IO$M_CREATE+IO$M_ACCESS,
	     &iosb,
	     0,
	     0,
	     &fib_descriptor,
	     &filespec_descriptor,
	     &len,
	     &resultant_name_descriptor,
	     acb,
	     0);
 
	if (iosb.status != SS$_NORMAL)
	{    /**  File creation failed **/
	    for (i = 0; i <= 2; i++)
		__FIB(fib,fib$r_fid_overlay,fib$w_fid[i]) = from_fid[i];
	    check_OK(sys$qiow (	    /**  Close the input file  **/
		     0,
		     chan,
		     IO$_DEACCESS,
		     &iosb,
		     0,
		     0,
		     &fib_descriptor,
		     0,
		     0,
		     0,
		     0,
		     0))
	    sys$dassgn (chan_o);
	    lib$sys_getmsg (
		&iosb.status,
		&len,
		&errmsg1_descrip,
		0,
		0);
	    errmsg1[len] = EOS;
	    strcpy(errmsg, errmsg1);
	    return DX__ERROR;
	}
 
	/*
	**  Copy to the output file by reading the virtual block(s)
	**  From the input file, stores it in a buffer, then writes it
	**  To the output file.
	**/
 
	status_flag = 0;
	svb = 1;
	sys$qiow (
	     0,
	     chan,
	     IO$_READVBLK,
	     &iosb,
	     0,
	     0,
	     buf,
	     BUFSIZ,
	     svb,
	     0,
	     0,
	     0);
 
	while (iosb.status == SS$_NORMAL)
	{
	    bytes = iosb.bytcnt;
	    sys$qiow (
		 0,
		 chan_o,
		 IO$_WRITEVBLK,
		 &iosb,
		 0,
		 0,
		 buf,
		 bytes,
		 svb,
		 0,
		 0,
		 0);
	    if (iosb.status != SS$_NORMAL)
	    {	    /**  WRITE A VIRTUAL BLOCK FAILED  **/
		status_flag++;
		sprintf(errmsg, "Error writing to %s", filespec);
		break;
	    }
	    svb++;
	    sys$qiow (
		 0,
		 chan,
		 IO$_READVBLK,
		 &iosb,
		 0,
		 0,
		 buf,
		 BUFSIZ,
		 svb,
		 0,
		 0,
		 0);
	}
 
	/*
	**  Close the output file.
	**  No error checking in case the output is SYS$OUTPUT.
	**/
 
	sys$qiow (
	     0,
	     chan_o,
	     IO$_DEACCESS,
	     &iosb,
	     0,
	     0,
	     &fib_descriptor,
	     0,
	     0,
	     0,
	     0,
	     0);
 
	sys$dassgn (chan_o);
 
	/**  Directory fid for the input file  **/
	for (i = 0; i <= 2; i++)
	{
	    __FIB(fib,fib$r_fid_overlay,fib$w_fid[i]) = from_fid[i];
	}
 
	sys$qiow (	/**  Close the input file  **/
	     0,
	     chan,
	     IO$_DEACCESS,
	     &iosb,
	     0,
	     0,
	     &fib_descriptor,
	     0,
	     0,
	     0,
	     0,
	     0);
    }
 
    if (status_flag)
	return DX__ERROR;
 
    /*
    **	Get output file attributes
    **/
 
    strncpy(filespec, to_nam.nam$l_dev, to_nam.nam$b_dev+to_nam.nam$b_dir);
    filespec[to_nam.nam$b_dev+to_nam.nam$b_dir] = EOS;
    strcat(filespec, resultant_name);
    if (filestat(filespec, &temp_entry, errmsg) == DX__ERROR)
    {
        return DX__ERROR;
    }
 
    /*
    **  Update cache queue.
    **	In case of running out of memory, output error message
    **	but update current display(s) anyway.
    **/
 
    if (update_filer_cache(temp_entry, add_to_filer_cache, errmsg) == DX__ERROR)
    {
        signal_err(errmsg, bell);
    }
 
    /**  Add it to the FILER  **/
    if (add_to_filer(temp_entry, errmsg, cntrl_info_block.cur_win) == DX__ERROR)
    {
        return DX__ERROR;
    }
 
 
    /**  Update other windows  **/
    for (i = 0;  i < cntrl_info_block.windows;  i++)
    {
    	if (i != cntrl_info_block.cur_win)
	{
	    check_OK(smg$set_physical_cursor (
                     &cntrl_info_block.pasteboard_id,
                     &cntrl_info_block.pasteboard_rows,
                     &1))
	    if (add_to_filer(temp_entry, errmsg, i) == DX__ERROR)
	    {
	    	 return DX__ERROR;
	    }
	}
    }
 
    return DX__NORMAL;
}
 
 

/*
**++
**  FUNCTIONAL DESCRIPTION:
**
**      to be specified
**
**--
**/
int	add_to_filer(
	struct fil_dx_tag e,
	char *errmsg,
	unsigned short int win)
{
    char dirname[NAM$C_MAXRSS];
    char fn[NAM$C_MAXRSS];
    struct filespec_list_tag *s;
    struct w_dids_tag *t;
    struct fil_dx_tag *p, *q;
    int row, col;
    int total_dids;
    char equ_name[MAXFILESPEC+1];
    int total_devices;
    char dev_name[MAXFILESPEC+1];
    unsigned short len;
    char str[MAXFILESPEC+1];
    $DESCRIPTOR (str_descrip, str);
    int next_entry_row, next_entry_column;
 
    fn[0] = EOS;
 
    /*
    **	Find out the number of equivalent names of current directory
    **/
 
    total_dids = 0;
    equ_name[0] = EOS;
    total_devices = 0;
    dev_name[0] = EOS;
    for (s = cntrl_info_block.dir_dx[win].cur_filter.name_filespec_list;
	s;  s = s->next)
    {
        for (t = s->w_dids;  t;  t = t->next)
        {
            if (strcmp (t->equivalent_name, equ_name))
            {
                total_dids++;
                strcpy (equ_name, t->equivalent_name);
            }
	    len = strcspn (t->equivalent_name, "[");
            if (strncmp (t->equivalent_name, dev_name, len))
            {
                total_devices++;
                strncpy (dev_name, t->equivalent_name, len);
            }
            if (t->did[0] == e.did[0] &&
		t->did[1] == e.did[1] &&
		t->did[2] == e.did[2])
            {
                strcpy(fn, t->equivalent_name);
            }
        }
    }
 
    if (strlen(fn) == 0)
    {	    /**  Directories not matched  **/
	return DX__NORMAL;
    }
 
    if (!strcmp(strrchr(e.fn, '.'), ".DIR;1"))
    {	    /**  Insert a directory file  **/
	char *cp;
	char s[MAXFILESPEC+1];
 
	strcpy(s, e.fn);
	cp = strrchr(s, '.');
        *cp = ']';      /**  Delete "DIR;1"  **/
	*++cp = EOS;
        if (total_dids <= 1)
        {
	    sprintf(e.fn, "[.%s", s);
        }
        else
        {
            if (total_devices <= 1)
            {
                strcpy (e.fn, strchr (fn, '['));
            }
	    else
	    {
		strcpy (e.fn, fn);
	    }
	    e.fn[strlen(e.fn)-1] = '.';
	    strcat (e.fn, s);
        }
 
        if (insert_filelist_entry(
		cntrl_info_block.dir_dx[win].dir_filelist,
		e,
		cntrl_info_block.dir_dx[win].sortby,
		cntrl_info_block.dir_dx[win].sortorder) == DX__NORMAL)
        {
            cntrl_info_block.dir_dx[win].tot_files++;
	    cntrl_info_block.dir_dx[win].tot_blocks += e.filesize;
	    cntrl_info_block.dir_dx[win].subdir++;
        }
    }
    else
    {	    /**  Regular file  **/
	if (find_exclude_file(	    /**  Update exclude list  **/
		&cntrl_info_block.dir_dx[win].exclude_filelist,
		cntrl_info_block.dir_dx[win].cur_filter,
		cntrl_info_block.dir_dx[win].sortby,
		cntrl_info_block.dir_dx[win].sortorder) == DX__ERROR)
	{
	    strcpy(
		errmsg, "Insufficient memory to update the exclude file list");
	    return DX__ERROR;
	}
 
	strcat(fn, e.fn);		    /**  Get full path name  **/
	if (!find_match_file(fn, win))  /**  The new file is not in the list  **/
	{
	    return DX__NORMAL;
	}
 
	/*
	**	Insert the new file to the list.  Make sure it meets all
	**	the file selection criteria before insertion.
	**/
 
	if (total_dids > 1)
	{
	    if (total_devices <= 1)
	    {
		strcpy(e.fn, strchr(fn, '['));
	    }
	    else
	    {
		strcpy(e.fn, fn);
	    }
	}
 
	if (!filter_OK(
		e,
		cntrl_info_block.dir_dx[win].exclude_filelist,
		cntrl_info_block.dir_dx[win].cur_filter))
	{
	    return DX__NORMAL;
	}
 
	if (insert_filelist_entry(
		cntrl_info_block.dir_dx[win].non_dir_filelist,
		e,
		cntrl_info_block.dir_dx[win].sortby,
		cntrl_info_block.dir_dx[win].sortorder) == DX__NORMAL)
	{
	    cntrl_info_block.dir_dx[win].tot_files++;
	    cntrl_info_block.dir_dx[win].tot_blocks += e.filesize;
	}
    }
 
    /*
    **	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 (p->fid[0] == e.fid[0] &&
		p->fid[1] == e.fid[1] &&
		p->fid[2] == e.fid[2])
	    {
		break;
	    }
	}
    }
 
    if (p == cntrl_info_block.dir_dx[win].non_dir_filelist)
    {
        return DX__NORMAL;
    }
 
    if (p->forward == cntrl_info_block.dir_dx[win].non_dir_filelist)
    {	    /**  p is the last entry in non-directory file list  **/
        next_entry_row = next_entry_column = INT_MAX;
    }
    else if (p->forward == cntrl_info_block.dir_dx[win].dir_filelist)
    {	    /**  p is the last entry in directory file list  **/
        next_entry_row = cntrl_info_block.dir_dx[win].non_dir_filelist->forward->beg_y;
        next_entry_column = cntrl_info_block.dir_dx[win].non_dir_filelist->forward->beg_x;
    }
    else
    {
        next_entry_row = p->forward->beg_y;
        next_entry_column = p->forward->beg_x;
    }
 
    /*
    **	Re-compute the position of the files in this directory
    **/
 
    row = col = 1;
    compute_filer_begin_xy (
	cntrl_info_block.dir_dx[win].dir_filelist, &row, &col, win);
    cntrl_info_block.dir_dx[win].non_dir_filelist->beg_y =
	cntrl_info_block.dir_dx[win].dir_filelist->backward->beg_y;
    cntrl_info_block.dir_dx[win].non_dir_filelist->beg_x =
	cntrl_info_block.dir_dx[win].dir_filelist->backward->beg_x;
    compute_filer_begin_xy (
	cntrl_info_block.dir_dx[win].non_dir_filelist, &row, &col, win);
 
    /*
    **	Adjust FILER_DISPLAY rows
    **/
 
    cntrl_info_block.dir_dx[win].filer_display.rows =
	max (cntrl_info_block.dir_dx[win].non_dir_filelist->backward->beg_y,
	     cntrl_info_block.dir_dx[win].filer_display.view_rows);
    check_OK(smg$change_virtual_display (
		 &cntrl_info_block.dir_dx[win].filer_display.id,
		 &cntrl_info_block.dir_dx[win].filer_display.rows,
		 &cntrl_info_block.dir_dx[win].filer_display.width,
		 0,
		 0,
		 0))
 
    /*
    **	Update screen with batch mode
    **/
 
    check_OK(smg$begin_display_update (
		 &cntrl_info_block.dir_dx[win].filer_display.id))
 
    if (cntrl_info_block.dir_dx[win].form == long_form)
    {
	if (p->beg_y < cntrl_info_block.dir_dx[win].filer_display.rows)
	{
	    check_OK(smg$insert_line (
			 &cntrl_info_block.dir_dx[win].filer_display.id,
			 &p->beg_y,
			 0,
			 &SMG$M_DOWN,
			 0,
			 0,
			 0,
			 0))
        }
	format_filer_entry(p, str, win);
 
        if (p->fn[ strlen(p->fn)-1 ] != ']')
	{
	    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))
	}
	else
	{
	    LENGTH(str_descrip) = 1;
	    check_OK(smg$put_chars (
			&cntrl_info_block.dir_dx[win].filer_display.id,
			&str_descrip,
			&p->beg_y,
			&1,
			0,
			0,
			0,
			0))
            memcpy (str, str+1, strlen(str));
	    LENGTH(str_descrip) = 30;
	    check_OK(smg$put_chars (
			&cntrl_info_block.dir_dx[win].filer_display.id,
			&str_descrip,
			&p->beg_y,
			&2,
			0,
			&SMG$M_BOLD,
			0,
			0))
	    memcpy (str, str+30, strlen(str)-30+1);
	    LENGTH(str_descrip) = strlen(str);
	    check_OK(smg$put_chars (
			&cntrl_info_block.dir_dx[win].filer_display.id,
			&str_descrip,
			&p->beg_y,
			&32,
			0,
			0,
			0,
			0))
        }
    }
    else
    {	    /**  Short form  **/
        if (next_entry_row < p->beg_y ||
	    (next_entry_row == p->beg_y && next_entry_column < p->beg_x))
        {
	    check_OK(smg$erase_display (
		      &cntrl_info_block.dir_dx[win].filer_display.id,
		      &next_entry_row,
		      &next_entry_column,
		      &cntrl_info_block.dir_dx[win].filer_display.rows,
		      &cntrl_info_block.dir_dx[win].filer_display.width))
        }
        else
        {
	    check_OK(smg$erase_display (
		      &cntrl_info_block.dir_dx[win].filer_display.id,
		      &p->beg_y,
		      &p->beg_x,
		      &cntrl_info_block.dir_dx[win].filer_display.rows,
		      &cntrl_info_block.dir_dx[win].filer_display.width))
        }
        for (q = p;
	    q != cntrl_info_block.dir_dx[win].non_dir_filelist;
	    q = q->forward)
        {
            if (q == cntrl_info_block.dir_dx[win].dir_filelist)
            {
                q = cntrl_info_block.dir_dx[win].non_dir_filelist;
            }
            else
            {
		format_filer_entry(q, str, win);
		LENGTH(str_descrip) = strlen(str);
                if (q->fn[ strlen(q->fn)-1 ] == ']')
                {
		    check_OK(smg$put_chars (
				 &cntrl_info_block.dir_dx[win].filer_display.id,
				 &str_descrip,
				 &q->beg_y,
				 &q->beg_x,
				 0,
				 &SMG$M_BOLD,
				 0,
				 0))
                }
                else
                {
		    check_OK(smg$put_chars (
				 &cntrl_info_block.dir_dx[win].filer_display.id,
				 &str_descrip,
				 &q->beg_y,
				 &q->beg_x,
				 0,
				 0,
				 0,
				 0))
                }
            }
        }
    }
 
    change_filer_viewport(win);
 
    check_OK(smg$end_display_update (
		 &cntrl_info_block.dir_dx[win].filer_display.id))
 
    put_filer_stat(win);
 
    return DX__NORMAL;
}
