home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
thesrc15.zip
/
file.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-17
|
44KB
|
1,394 lines
/***********************************************************************/
/* FILE.C - File and view related functions. */
/***********************************************************************/
/*
* THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
* Copyright (C) 1991-1993 Mark Hessling
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
*
* The Free Software Foundation, Inc.
* 675 Mass Ave,
* Cambridge, MA 02139 USA.
*
*
* If you make modifications to this software that you feel increases
* it usefulness for the rest of the community, please email the
* changes, enhancements, bug fixes as well as any and all ideas to me.
* This software is going to be maintained and enhanced as deemed
* necessary by the community.
*
* Mark Hessling email: M.Hessling@gu.edu.au
* 36 David Road Phone: +61 7 849 7731
* Holland Park Fax: +61 7 875 5314
* QLD 4121
* Australia
*/
/*
$Header: C:\THE\RCS\file.c 1.4 1993/09/01 16:26:23 MH Interim MH $
*/
#include <stdio.h>
#include <errno.h>
#include "the.h"
#include "directry.h"
#include "proto.h"
#if defined(DOS) || defined(OS2)
#include <io.h>
#endif
/****************** needs to be fixed *************/
#ifdef GO32
#define stricmp strcasecmp
#endif
/*#define TRACE*/
/*-------------------------- external data ----------------------------*/
extern LINE *next_line,*curr_line;
extern VIEW_DETAILS *vd_current,*vd_first,*vd_mark;
extern char current_screen;
extern SCREEN_DETAILS screen[MAX_SCREENS]; /* screen structures */
extern WINDOW *foot,*error_window;
extern bool error_on_screen;
extern char number_of_views;
extern char number_of_files;
extern char display_screens; /* number of screens */
extern char *rec;
extern unsigned short rec_len;
extern char *cmd_rec;
extern unsigned short cmd_rec_len;
extern char in_profile; /* indicates if processing profile */
extern char mode_insert; /* defines insert mode toggle */
extern char file_disposition;
extern struct stat stat_buf;
extern char *temp_cmd;
extern char dir_filename[10];
extern char dir_pathname[MAX_FILE_NAME+1];
#if !defined(NOREXX)
extern char *rexxoutname;
extern char rexx_filename[10];
extern char rexx_pathname[MAX_FILE_NAME+1];
#endif
extern char sp_path[MAX_FILE_NAME+1] ;
extern char sp_fname[MAX_FILE_NAME+1] ;
extern char dir_path[MAX_FILE_NAME+1] ; /* for dir and ls commands */
/***********************************************************************/
#ifdef PROTO
short get_file(char *filename)
#else
short get_file(filename)
char *filename;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern char CMD_LINEx;
extern char ERROR_ROWx;
extern char TAB_ROWx;
extern char TAB_ONx;
extern char SCALE_ROWx;
extern char SCALE_ONx;
extern char PREFIXx;
extern char CURRENT_ROW_POSx;
extern char STAYx;
extern char CASE_Ex;
extern char CASE_Lx;
extern char CASE_Cx;
extern char TABO_ONx;
extern char TABO_Nx;
extern char TABSx;
/*--------------------------- local data ------------------------------*/
char fno;
LINE *curr;
char work_filename[MAX_FILE_NAME+1] ;
VIEW_DETAILS *save_current_view,*found_file;
int rc;
bool directory_file=FALSE;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("file.c: get_file");
#endif
/*---------------------------------------------------------------------*/
/* Split the filename supplied into directory and filename parts. */
/* This is done before allocating a new current_file number. */
/*---------------------------------------------------------------------*/
if ((rc = splitpath(filename)) != RC_OK)
{
display_error(10,filename);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/*---------------------------------------------------------------------*/
/* If the filename portion of the splithpath is empty, then we are */
/* editing a directory. So create the new file with the appropriate OS*/
/* command and set the filename to DIR.DIR. */
/*---------------------------------------------------------------------*/
if (strcmp(sp_fname,"") == 0)
{
if ((rc = read_directory()) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
strcpy(sp_path,dir_pathname);
strcpy(sp_fname,dir_filename);
}
/*---------------------------------------------------------------------*/
/* If this is the first file to be edited, don't check to see if the */
/* file is already in the ring. Obvious hey! */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW == (VIEW_DETAILS *)NULL) /* no files in ring yet */
{
if ((rc = defaults_for_first_file()) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
}
else
{
/*---------------------------------------------------------------------*/
/* Here we should check if we already have the file to be edited in */
/* the ring. If the file is there and it is DIR.DIR, QQUIT out of it */
/* otherwise set the current pointer to it and exit. */
/* Same applies to REXX output file. */
/*---------------------------------------------------------------------*/
save_current_view = CURRENT_VIEW;
if ((found_file = find_file(sp_path,sp_fname)) != (VIEW_DETAILS *)NULL)
{
CURRENT_VIEW = found_file;
/* if (CURRENT_FILE->pseudo_file == PSEUDO_DIR
|| CURRENT_FILE->pseudo_file == PSEUDO_REXX)*/
#if !defined(NOREXX)
if ((strcmp(CURRENT_FILE->fname,dir_filename) == 0
&& strcmp(CURRENT_FILE->fpath,dir_pathname) == 0)
|| (strcmp(CURRENT_FILE->fname,rexx_filename) == 0
&& strcmp(CURRENT_FILE->fpath,rexx_pathname) == 0))
#else
if ((strcmp(CURRENT_FILE->fname,dir_filename) == 0
&& strcmp(CURRENT_FILE->fpath,dir_pathname) == 0))
#endif
{
Qquit("");
if (CURRENT_VIEW == (VIEW_DETAILS *)NULL)
rc = defaults_for_first_file();
else
rc = defaults_for_other_files();
if (rc != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
}
else
{
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
}
else
{
CURRENT_VIEW = save_current_view;
if ((rc = defaults_for_other_files()) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
}
}
/*---------------------------------------------------------------------*/
/* Increment the number of files in storage here, so that if there are */
/* any problems with reading the file, free_file_memory() function can */
/* correctly decrement the number of files. */
/*---------------------------------------------------------------------*/
number_of_files++;
/*---------------------------------------------------------------------*/
/* Allocate memory to file pointer. */
/*---------------------------------------------------------------------*/
if ((CURRENT_FILE = (FILE_DETAILS *)malloc(sizeof(FILE_DETAILS))) == (FILE_DETAILS *)NULL)
{
free_view_memory();
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
/*---------------------------------------------------------------------*/
/* Set up default file attributes. */
/*---------------------------------------------------------------------*/
default_file_attributes();
if (strcmp(dir_filename,sp_fname) == 0)
CURRENT_FILE->pseudo_file = PSEUDO_DIR;
#if !defined(NOREXX)
if (strcmp(rexxoutname,sp_fname) == 0)
CURRENT_FILE->pseudo_file = PSEUDO_REXX;
#endif
/*---------------------------------------------------------------------*/
/* Copy the filename and path strings split up at the start of the */
/* function. */
/*---------------------------------------------------------------------*/
if ((CURRENT_FILE->fname = (char *)malloc(strlen(sp_fname)+1)) == NULL)
{
free_view_memory();
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
if ((CURRENT_FILE->fpath = (char *)malloc(strlen(sp_path)+1)) == NULL)
{
free_view_memory();
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
strcpy(CURRENT_FILE->fname,sp_fname);
strcpy(CURRENT_FILE->fpath,sp_path);
strcpy(work_filename,sp_path);
strcat(work_filename,sp_fname);
/*---------------------------------------------------------------------*/
/* If the file is not readable, then display error. */
/*---------------------------------------------------------------------*/
if (!file_readable(work_filename))
{
display_error(8,work_filename);
free_view_memory();
#ifdef TRACE
trace_return();
#endif
return(RC_ACCESS_DENIED);
}
if (file_exists(work_filename))
{
if (file_writable(work_filename))
file_disposition = FILE_NORMAL;
else
{
file_disposition = FILE_READONLY;
if (!in_profile)
display_error(0,(char *)"File is read-only...");
}
if ((CURRENT_FILE->fp = fopen(work_filename,"r")) == NULL)
{
#ifdef TRACE
trace_return();
#endif
return(RC_ACCESS_DENIED);
}
}
else
{
file_disposition = FILE_NEW;
if (!in_profile)
display_error(0,(char *)"New file...");
}
/*---------------------------------------------------------------------*/
/* first_line is set to "Top of File" */
/*---------------------------------------------------------------------*/
if ((CURRENT_FILE->first_line = add_line(CURRENT_FILE->first_line,NULL,TOP_OF_FILE,
strlen(TOP_OF_FILE))) == NULL)
{
free_view_memory();
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
curr = CURRENT_FILE->first_line;
/*---------------------------------------------------------------------*/
/* Read in the existing file... */
/*---------------------------------------------------------------------*/
CURRENT_FILE->number_lines = 0L;
if (file_disposition != FILE_NEW)
{
stat(work_filename,&stat_buf);
CURRENT_FILE->fmode = stat_buf.st_mode;
if ((curr = read_file(CURRENT_FILE->fp,curr,work_filename)) == NULL)
{
free_view_memory();
#ifdef TRACE
trace_return();
#endif
return(RC_ACCESS_DENIED);
}
}
else
CURRENT_FILE->fmode = FMODE;
/*---------------------------------------------------------------------*/
/* last line is set to "Bottom of File" */
/*---------------------------------------------------------------------*/
if (add_line(CURRENT_FILE->first_line,curr,BOTTOM_OF_FILE,
strlen(BOTTOM_OF_FILE)) == NULL)
{
free_view_memory();
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
if (file_disposition != FILE_NEW)
fclose(CURRENT_FILE->fp);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
LINE *read_file(FILE *fp,LINE *curr,char *filename)
#else
LINE *read_file(fp,curr,filename)
FILE *fp;
LINE *curr;
char *filename;
#endif
/***********************************************************************/
{
/*-------------------------- external data ----------------------------*/
extern char TABI_ONx;
extern char TABI_Nx;
/*--------------------------- local data ------------------------------*/
register unsigned short i;
short ch;
LINE *temp;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("file.c: read_file");
#endif
temp = curr;
memset(rec,' ',max_line_length);
i = 0;
while(1)
{
ch = fgetc(fp);
if (feof(fp))
{
if (i > 0) /* line with no CR and/or CR/LF */
{
if ((temp = add_line(CURRENT_FILE->first_line,temp,rec,i)) == NULL)
{
#ifdef TRACE
trace_return();
#endif
return(NULL);
}
CURRENT_FILE->number_lines++;
}
break;
}
if (ch == '\t'&& TABI_ONx)
{
do
{
rec[i] = ' ';
i++;
if (i >= max_line_length)
{
sprintf(rec,"Line %d exceeds max. width of %d",CURRENT_FILE->number_lines+1,max_line_length);
display_error(29,rec);
#ifdef TRACE
trace_return();
#endif
return(NULL);
}
}
while ((i % TABI_Nx) != 0);
continue;
}
if (ch == '\n')
{
rec[i] = '\0';
if ((temp = add_line(CURRENT_FILE->first_line,temp,rec,i)) == NULL)
{
#ifdef TRACE
trace_return();
#endif
return(NULL);
}
CURRENT_FILE->number_lines++;
i = 0;
memset(rec,' ',max_line_length);
continue;
}
if (ch == '\r')
{
rec[i] = ch;
i++;
ch = fgetc(fp);
if (feof(fp))
break;
if (ch == '\n')
{
--i;
rec[i] = '\0';
if ((temp = add_line(CURRENT_FILE->first_line,temp,rec,i)) == NULL)
{
#ifdef TRACE
trace_return();
#endif
return(NULL);
}
CURRENT_FILE->number_lines++;
i = 0;
memset(rec,' ',max_line_length);
continue;
}
}
rec[i] = ch;
i++;
if (i >= max_line_length)
{
sprintf(rec,"Line %d exceeds max. width of %d",CURRENT_FILE->number_lines+1,max_line_length);
display_error(29,rec);
#ifdef TRACE
trace_return();
#endif
return(NULL);
}
}
#ifdef TRACE
trace_return();
#endif
return(temp);
}
/***********************************************************************/
#ifdef PROTO
short save_file(FILE_DETAILS *cf,char *new_fname,char force,long in_lines,
long start_line,char append,int start_col, int end_col)
#else
short save_file(cf,new_fname,force,in_lines,start_line,append,start_col,end_col)
FILE_DETAILS *cf;
char *new_fname;
char force,append;
long in_lines,start_line;
int start_col,end_col;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
char *bak_filename=(char *)NULL;
char *write_fname=(char *)NULL;
register int i;
long j;
long num_lines=in_lines;
LINE *curr;
FILE *fp;
unsigned short col,newcol;
short off;
char c;
int rc;
bool same_file=TRUE;
int anerror;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("file.c: save_file");
#endif
if ((write_fname = (char *)malloc(MAX_FILE_NAME)) == NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
/*---------------------------------------------------------------------*/
/* If a new filename is specified, use it as the old filename. */
/*---------------------------------------------------------------------*/
(void *)strtrans(new_fname,OSLASH,ISLASH);
if (strcmp(new_fname,"") != 0) /* new_fname supplied */
{
/*---------------------------------------------------------------------*/
/* Split the supplied new filename. */
/*---------------------------------------------------------------------*/
if ((rc = splitpath(new_fname)) != RC_OK)
{
display_error(10,new_fname);
if (bak_filename != (char *)NULL)
free(bak_filename);
if (write_fname != (char *)NULL)
free(write_fname);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
strcpy(write_fname,sp_path);
strcat(write_fname,sp_fname);
same_file = FALSE;
/*---------------------------------------------------------------------*/
/* Test to make sure that the write fname doesn't exist... */
/* ...unless we are forcing the write. */
/*---------------------------------------------------------------------*/
if ((!force) && file_exists(write_fname))
{
display_error(31,write_fname);
if (bak_filename != (char *)NULL)
free(bak_filename);
if (write_fname != (char *)NULL)
free(write_fname);
#ifdef TRACE
trace_return();
#endif
return(RC_ACCESS_DENIED);
}
/*---------------------------------------------------------------------*/
/* Test to make sure that we can write the file. */
/*---------------------------------------------------------------------*/
if (!file_writable(write_fname))
{
display_error(8,write_fname);
if (bak_filename != (char *)NULL)
free(bak_filename);
if (write_fname != (char *)NULL)
free(write_fname);
#ifdef TRACE
trace_return();
#endif
return(RC_ACCESS_DENIED);
}
}
else
{
/*---------------------------------------------------------------------*/
/* We are using the same file name for the new file. */
/* Create the name of the current file. */
/*---------------------------------------------------------------------*/
strcpy(write_fname,cf->fpath);
strcat(write_fname,cf->fname);
/*---------------------------------------------------------------------*/
/* If the file exists, test to make sure we can write it and save a */
/* backup copy. */
/*---------------------------------------------------------------------*/
if (file_exists(write_fname))
{
/*---------------------------------------------------------------------*/
/* Test to make sure that we can write the file. */
/*---------------------------------------------------------------------*/
if (!file_writable(write_fname))
{
display_error(8,write_fname);
if (bak_filename != (char *)NULL)
free(bak_filename);
if (write_fname != (char *)NULL)
free(write_fname);
#ifdef TRACE
trace_return();
#endif
return(RC_ACCESS_DENIED);
}
/*---------------------------------------------------------------------*/
/* Rename the current file to filename.bak. */
/*---------------------------------------------------------------------*/
if ((bak_filename =
(char *)malloc(strlen(cf->fpath)+strlen(cf->fname)+5)) == NULL)
{
display_error(30,(char *)"");
if (bak_filename != (char *)NULL)
free(bak_filename);
if (write_fname != (char *)NULL)
free(write_fname);
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
new_filename(cf->fpath,cf->fname,bak_filename,(char *)".bak");
if (cf->fp != NULL)
{
remove_file(bak_filename);
if (rename(write_fname,bak_filename) != 0)
{
display_error(8,write_fname);
if (bak_filename != (char *)NULL)
free(bak_filename);
if (write_fname != (char *)NULL)
free(write_fname);
#ifdef TRACE
trace_return();
#endif
return(RC_ACCESS_DENIED);
}
}
}
}
/*---------------------------------------------------------------------*/
/* Open the file we are writing to... */
/*---------------------------------------------------------------------*/
if (append == YES)
fp = fopen(write_fname,"ab");
else
fp = fopen(write_fname,"wb");
if (fp == NULL)
{
display_error(8,(char *)"could not open for writing");
if (bak_filename != (char *)NULL)
free(bak_filename);
if (write_fname != (char *)NULL)
free(write_fname);
#ifdef TRACE
trace_return();
#endif
return(RC_ACCESS_DENIED);
}
/*---------------------------------------------------------------------*/
/* Determine where to start writing from in the linked list. */
/* If the number of lines is greater than zero, then only that many */
/* lines are written to the output file. */
/* When the number of lines is equal to zero, write out the whole file.*/
/*---------------------------------------------------------------------*/
if (num_lines > 0L) /* called from put(d) command */
#ifdef USE_VOID
curr = (LINE *)ll_find((LINE *)cf->first_line,start_line);
#else
curr = lll_find(cf->first_line,start_line);
#endif
else
{
curr = cf->first_line;
num_lines = cf->number_lines + 1; /* forces following for to work */
}
/*---------------------------------------------------------------------*/
/* Now write out the contents of the file array to the new filename. */
/*---------------------------------------------------------------------*/
rc = RC_OK;
for (j=0L;j<num_lines && curr->next != NULL;j++)
{
if (curr->prev != NULL) /* not first line */
{
if (cf->tabsout_on)
{
col = 0;
off = start_col;
while (1)
{
newcol = col;
while ((c = next_char(curr,&off,end_col+1)) == ' ')
{
newcol++;
if ((newcol % cf->tabsout_num) == 0)
{
if ((rc = write_char((char)'\t',fp)) == RC_DISK_FULL)
break;
col = newcol;
}
}
for (;col<newcol;col++)
if ((rc = write_char((char)' ',fp)) == RC_DISK_FULL)
break;
if (off == (-1)) /* end of line */
break;
if ((rc = write_char((char)c,fp)) == RC_DISK_FULL)
break;
col++;
}
if (rc) break;
}
else
{
for (i=start_col;i<min(curr->length,end_col+1);i++)
if ((rc = write_char((char)*(curr->line+i),fp)) == RC_DISK_FULL)
break;
}
if (rc) break;
/* col = 0;*/
if (cf->eolout == EOLOUT_CRLF)
{
if ((rc = write_char((char)'\r',fp)) == RC_DISK_FULL)
break;
}
if ((rc = write_char((char)'\n',fp)) == RC_DISK_FULL)
break;
}
if (rc) break;
curr = curr->next;
}
anerror = errno;
if (fflush(fp) == EOF)
{
rc = RC_DISK_FULL;
clearerr(fp);
}
if (fclose(fp) == EOF)
rc = RC_DISK_FULL;
if (rc)
clearerr(fp);
/*---------------------------------------------------------------------*/
/* If an error occurred in writing the file (usuallly a result of a */
/* disk full error), get the files back to the way they were before */
/* this attempt to write them. */
/*---------------------------------------------------------------------*/
if (rc)
{
/* remove 'new' file (the one that couldn't be written) */
remove_file(write_fname);
if (same_file)
{
if (rename(bak_filename,write_fname) != 0)
{
display_error(8,write_fname);
if (bak_filename != (char *)NULL)
free(bak_filename);
if (write_fname != (char *)NULL)
free(write_fname);
#ifdef TRACE
trace_return();
#endif
return(RC_ACCESS_DENIED);
}
}
}
else
{
if (cf->fmode != 0)
chmod(write_fname,cf->fmode);
/*---------------------------------------------------------------------*/
/* If a backup file is not to be kept, remove the backup file provided */
/* that there hasn't been a problem in writing the file. */
/*---------------------------------------------------------------------*/
if (!cf->backup)
remove_file(bak_filename);
/*---------------------------------------------------------------------*/
/* If a new filename was not supplied, free up temporary memory. */
/*---------------------------------------------------------------------*/
}
if (bak_filename != (char *)NULL)
free(bak_filename);
if (write_fname != (char *)NULL)
free(write_fname);
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef PROTO
int write_char(char chr,FILE *fp)
#else
int write_char(chr,fp)
char chr;
FILE *fp;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
if (fputc(chr,fp) == chr
&& ferror(fp) == 0)
return(RC_OK);
clearerr(fp);
display_error(57,(char *)"");
return(RC_DISK_FULL);
}
/***********************************************************************/
#ifdef PROTO
int increment_alt(FILE_DETAILS *cf)
#else
int increment_alt(cf)
FILE_DETAILS *cf;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i;
char *aus_filename;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("file.c: increment_alt");
#endif
cf->autosave_alt++;
cf->save_alt++;
/*---------------------------------------------------------------------*/
/* We can now test for autosave_alt exceeding the defined limit and */
/* carry out an autosave if necessary. */
/*---------------------------------------------------------------------*/
if (cf->autosave != 0
&& cf->autosave_alt >= cf->autosave)
{
if ((aus_filename =
(char *)malloc(strlen(cf->fpath)+strlen(cf->fname)+5)) == NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
new_filename(cf->fpath,cf->fname,aus_filename,(char *)".aus");
save_file(cf,aus_filename,YES,0L,0L,NO,0,max_line_length);
free(aus_filename);
cf->autosave_alt = 0;
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
char *new_filename(char *ofp,char *ofn,
char *nfn,char *ext)
#else
char *new_filename(ofp,ofn,nfn,ext)
char *ofp,*ofn,*nfn,*ext;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
short rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("file.c: new_filename");
#endif
strcpy(nfn,ofp);
strcat(nfn,ofn);
#ifdef DOS
rc = strzeq(nfn,'.');
if (rc != (-1))
*(nfn+rc) = '\0';
#endif
#ifdef OS2
if (!LongFileNames(nfn)) /* returns TRUE if HPFS filesystem */
{
rc = strzreveq(nfn,'.');
if (rc != (-1))
*(nfn+rc) = '\0';
}
#endif
strcat(nfn,ext);
#ifdef TRACE
trace_return();
#endif
return(nfn);
}
/***********************************************************************/
#ifdef PROTO
int remove_aus_file(FILE_DETAILS *cf)
#else
int remove_aus_file(cf)
FILE_DETAILS *cf;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register short i;
char *aus_filename;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("file.c: remove_aus_file");
#endif
if ((aus_filename =
(char *)malloc(strlen(cf->fpath)+strlen(cf->fname)+5)) == NULL)
{
display_error(30,(char *)"");
#ifdef TRACE
trace_return();
#endif
return(RC_OUT_OF_MEMORY);
}
new_filename(cf->fpath,cf->fname,aus_filename,(char *)".aus");
remove_file(aus_filename);
free(aus_filename);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int free_view_memory(void)
#else
int free_view_memory()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
char save_current_screen;
short original_number_of_files=number_of_files;
int rc;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("file.c: free_view_memory");
#endif
if (--CURRENT_FILE->file_views == 0)
free_file_memory();
free_a_view();
/*---------------------------------------------------------------------*/
/* The following procedures are only carried out when the number of */
/* screens is > 1. */
/*---------------------------------------------------------------------*/
if (display_screens > 1)
{
/*---------------------------------------------------------------------*/
/* +---+---+ +---+---+ +---+---+ +---+---+ */
/* | a | b | | a | a | or | a | b | c | a | a | */
/* | | | --> | | | | | | | | | */
/* | |qq | | | | | |qq | | | | */
/* +---+---+ +---+---+ +---+---+ +---+---+ */
/* number_of_files > 1 */
/*---------------------------------------------------------------------*/
if (original_number_of_files > 1 && OTHER_SCREEN.screen_view != (VIEW_DETAILS *)NULL)
if (CURRENT_SCREEN.screen_view->file_for_view !=
OTHER_SCREEN.screen_view->file_for_view)
{
if ((rc = defaults_for_other_files()) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
CURRENT_FILE = OTHER_SCREEN.screen_view->file_for_view;
CURRENT_FILE->file_views++;
if ((rc = set_up_windows()) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
CURRENT_SCREEN.screen_view = CURRENT_VIEW;
/* repaint_screen(); */
}
else
/*---------------------------------------------------------------------*/
/* +---+---+ +---+---+ +---+---+ +---+---+ */
/* | a | a | b | b | b | or | a | a | b c | b | b | */
/* | | | --> | | | | | | | | | */
/* | |qq | | | | | |qq | | | | */
/* +---+---+ +---+---+ +---+---+ +---+---+ */
/* number_of_files > 1 */
/*---------------------------------------------------------------------*/
{
free_file_memory();
free_a_view();
if ((rc = defaults_for_other_files()) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
if ((rc = set_up_windows()) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
OTHER_SCREEN.screen_view = CURRENT_VIEW;
CURRENT_FILE = OTHER_SCREEN.screen_view->file_for_view;
repaint_screen();
if ((rc = set_up_windows()) != RC_OK)
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
CURRENT_SCREEN.screen_view = CURRENT_VIEW;
CURRENT_FILE->file_views++;
}
/*---------------------------------------------------------------------*/
/* +---+---+ */
/* | a | a | */
/* | | | --> exit */
/* |qq | | */
/* +---+---+ */
/* number_of_files = 1 */
/*---------------------------------------------------------------------*/
if (original_number_of_files == 1 && OTHER_SCREEN.screen_view != (VIEW_DETAILS *)NULL)
if (CURRENT_SCREEN.screen_view->file_for_view ==
OTHER_SCREEN.screen_view->file_for_view)
{
CURRENT_FILE->file_views--;
free_file_memory();
free_a_view();
}
}
if (number_of_views > 0
&& !in_profile)
{
pre_process_line(CURRENT_VIEW->focus_line);
show_page();
if (CURRENT_VIEW->prefix)
touchwin(CURRENT_WINDOW_PREFIX);
touchwin(CURRENT_WINDOW_COMMAND);
touchwin(CURRENT_WINDOW_IDLINE);
touchwin(CURRENT_WINDOW_MAIN);
touchwin(CURRENT_WINDOW);
show_heading();
}
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
void free_a_view(void)
#else
void free_a_view()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("file.c: free_a_view");
#endif
/*---------------------------------------------------------------------*/
/* If the marked block is within the current view, unset the variables.*/
/*---------------------------------------------------------------------*/
if (MARK_VIEW == CURRENT_VIEW)
MARK_VIEW = (VIEW_DETAILS *)NULL;
/*---------------------------------------------------------------------*/
/* Delete the windows associated with the current view. */
/* Only do this if we are running interactively. */
/*---------------------------------------------------------------------*/
if (!in_profile && CURRENT_WINDOW_MAIN != (WINDOW *)NULL)
{
if (CURRENT_VIEW->prefix)
delwin(CURRENT_WINDOW_PREFIX);
delwin(CURRENT_WINDOW_MAIN);
delwin(CURRENT_WINDOW_COMMAND);
delwin(CURRENT_WINDOW_ARROW);
delwin(CURRENT_WINDOW_IDLINE);
}
#ifdef USE_VOID
if ((CURRENT_VIEW = (VIEW_DETAILS *)ll_del((void *)vd_first,(void *)CURRENT_VIEW,DIRECTION_FORWARD)) == (VIEW_DETAILS *)NULL)
#else
CURRENT_VIEW = vll_del(&vd_first,NULL,CURRENT_VIEW,DIRECTION_FORWARD);
#endif
number_of_views--;
return;
}
/***********************************************************************/
#ifdef PROTO
int free_file_memory(void)
#else
int free_file_memory()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
LINE *curr;
register int i;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("file.c: free_file_memory");
#endif
if (CURRENT_FILE->fname != NULL)
{
free(CURRENT_FILE->fname);
CURRENT_FILE->fname = (char *)NULL;
}
if (CURRENT_FILE->fpath != NULL)
{
free(CURRENT_FILE->fpath);
CURRENT_FILE->fpath = (char *)NULL;
}
#ifdef USE_VOID
ll_free((void *)CURRENT_FILE->first_line);
#else
CURRENT_FILE->first_line = lll_free(CURRENT_FILE->first_line);
#endif
if (CURRENT_FILE != NULL)
{
free(CURRENT_FILE);
CURRENT_FILE = (FILE_DETAILS *)NULL;
}
number_of_files--;
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
int read_directory(void)
#else
int read_directory()
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
struct dirfile *dpfirst=NULL,*dplast=NULL,*dp;
char str_attr[11];
char str_date[10];
char str_time[6];
#ifdef UNIX
struct tm *timp;
#endif
int rc;
FILE *fp;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("file.c: read_directory");
#endif
/*---------------------------------------------------------------------*/
/* Get all file info for the selected files into structure. If no file */
/* name specified, force it to '*'. */
/*---------------------------------------------------------------------*/
if (strcmp(sp_fname,"") == 0)
rc = getfiles(sp_path,(char *)"*",&dpfirst,&dplast);
else
rc = getfiles(sp_path,sp_fname,&dpfirst,&dplast);
if (rc != RC_OK)
{
display_error(rc,sp_path);
#ifdef TRACE
trace_return();
#endif
return(RC_FILE_NOT_FOUND);
}
if (dpfirst == dplast)
{
display_error(9,sp_path);
#ifdef TRACE
trace_return();
#endif
return(RC_FILE_NOT_FOUND);
}
/*---------------------------------------------------------------------*/
/* dir_path is set up here so that subsequent sos_edit commands can use*/
/* the directory path as a prefix to the edit files filename. */
/*---------------------------------------------------------------------*/
strcpy(dir_path,sp_path);
/*---------------------------------------------------------------------*/
/* sort the array of file structures. */
/*---------------------------------------------------------------------*/
qsort(dpfirst,dplast - dpfirst,sizeof(struct dirfile),fcomp);
/*---------------------------------------------------------------------*/
/* open the DIR.DIR file for output, overwriting any previous data */
/*---------------------------------------------------------------------*/
strcpy(temp_cmd,dir_pathname);
strcat(temp_cmd,dir_filename);
if ((fp = fopen(temp_cmd,"w")) == NULL)
{
display_error(8,sp_path);
#ifdef TRACE
trace_return();
#endif
return(RC_ACCESS_DENIED);
}
/*---------------------------------------------------------------------*/
/* write out the formatted contents of the file structures. */
/*---------------------------------------------------------------------*/
for (dp=dpfirst;dp<dplast;dp++)
{
#ifdef UNIX
timp = localtime(&(dp->ftime));
#endif
fprintf(fp,"%s ",file_attrs(dp->fattr,str_attr));
fprintf(fp,"%8ld ",dp->fsize);
fprintf(fp,"%s ",file_date(D_NAME,str_date));
fprintf(fp,"%s ",file_time(T_NAME,str_time));
fprintf(fp,"%s\n",dp->fname);
free(dp->fname);
}
free(dpfirst);
fclose(fp);
#ifdef TRACE
trace_return();
#endif
return(RC_OK);
}
/***********************************************************************/
#ifdef PROTO
VIEW_DETAILS *find_file(char *fp,char *fn)
#else
VIEW_DETAILS *find_file(fp,fn)
char *fp,*fn;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
VIEW_DETAILS *save_current_view,*found_file;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("file.c: find_file");
#endif
save_current_view = CURRENT_VIEW;
CURRENT_VIEW = vd_first;
while(CURRENT_VIEW != (VIEW_DETAILS *)NULL)
{
#ifdef UNIX
if (strcmp(CURRENT_FILE->fname,fn) == 0
&& strcmp(CURRENT_FILE->fpath,fp) == 0)
#else
if (stricmp(CURRENT_FILE->fname,fn) == 0
&& stricmp(CURRENT_FILE->fpath,fp) == 0)
#endif
{
#ifdef TRACE
trace_return();
#endif
found_file = CURRENT_VIEW;
CURRENT_VIEW = save_current_view;
return(found_file);
}
CURRENT_VIEW = CURRENT_VIEW->next;
}
#ifdef TRACE
trace_return();
#endif
CURRENT_VIEW = save_current_view;
return((VIEW_DETAILS *)NULL);
}
/***********************************************************************/
#ifdef PROTO
int execute_command_file(FILE *fp)
#else
int execute_command_file(fp)
FILE *fp;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
register int i;
char ch;
int rc=RC_OK;
char profile_command_line[MAX_COMMAND_LENGTH];
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("file.c: execute_command_file");
#endif
memset(profile_command_line,' ',MAX_COMMAND_LENGTH);
i = 0;
while(1)
{
ch = fgetc(fp);
if (feof(fp))
break;
if (ch == '\n')
{
profile_command_line[i] = '\0';
rc = process_command_line(profile_command_line);
if (number_of_files == 0)
break;
i = 0;
memset(profile_command_line,' ',MAX_COMMAND_LENGTH);
continue;
}
if (ch == '\r')
{
profile_command_line[i] = ch;
i++;
ch = fgetc(fp);
if (feof(fp))
break;
if (ch == '\n')
{
--i;
profile_command_line[i] = '\0';
rc = process_command_line(profile_command_line);
if (number_of_files == 0)
break;
i = 0;
memset(profile_command_line,' ',MAX_COMMAND_LENGTH);
continue;
}
}
profile_command_line[i] = ch;
i++;
}
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/***********************************************************************/
#ifdef PROTO
int process_command_line(char *profile_command_line)
#else
int process_command_line(profile_command_line)
char *profile_command_line;
#endif
/***********************************************************************/
{
/*--------------------------- local data ------------------------------*/
int rc=RC_OK;
int len;
bool strip=FALSE;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("file.c: process_command_line");
#endif
/*---------------------------------------------------------------------*/
/* If the line begins with a comment, just return. */
/*---------------------------------------------------------------------*/
if (memcmp(profile_command_line,"/*",2) == 0) /* is a comment line */
{
#ifdef TRACE
trace_return();
#endif
return(rc);
}
/*---------------------------------------------------------------------*/
/* If the line begins and ends with a quote, single or double, strip */
/* the quotes. */
/*---------------------------------------------------------------------*/
len = strlen(profile_command_line);
if (*(profile_command_line) == '\''
&& *(profile_command_line+len-1) == '\'')
strip = TRUE;
if (*(profile_command_line) == '"'
&& *(profile_command_line+len-1) == '"')
strip = TRUE;
if (strip)
{
*(profile_command_line+len-1) = '\0';
profile_command_line++;
}
rc = command_line(profile_command_line,COMMAND_ONLY_FALSE);
#ifdef TRACE
trace_return();
#endif
return(rc);
}