home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
most423.zip
/
file.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-28
|
10KB
|
456 lines
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#ifndef toupper
#define toupper(c) ((c)-'a'+'A')
#endif
#ifndef VMS
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#else
#include <types.h>
#include <stat.h>
#include <stdlib.h>
#endif
#ifndef O_RDONLY
#define O_RDONLY 0
#endif
#include "externs.h"
#include "file.h"
#include "keym.h"
#include "buffer.h"
#include "window.h"
#include "display.h"
#include "sysdep.h"
char *FILE_RING[500];
char C_DIR[256]; /* current working dir */
int NUM_FILES;
extern int SCREEN_WIDTH;
int insert_file(char *file)
{
struct stat st;
int size = 0, fd;
#ifdef VMS
unsigned recsz = 512;
extern int stat(char *, struct stat *);
#endif
if (file[0] == '\0') /* assume stdin */
{
fd = 0;
strcpy(BUF->file,"(Standard Input)");
}
else
{
if (stat(file, &st)) return(-1);
if (st.st_mode & S_IFDIR) /* S_IFDIR = 0040000 */
{
#ifndef VMS
return get_dir(file);
#else
return(-1);
#endif
}
size = st.st_size;
#ifdef VMS
recsz = st.st_fab_mrs;
if (recsz <= 255) recsz = 255;
/* VMS share options (shr=put) suggested by Henk D. Davids <hdavids@mswe.dnet.ms.philips.nl> */
/* VMS share options (shr=upi,get,put) suggested by Mark Pizzolato <mark@infocomm.com> */
fd = open(file,O_RDONLY,"ctx=rec","mbf=8","mbc=16","rop=RAH","shr=upi,get,put");
/* if (fd < 0) fd = open(file,O_RDONLY); */
#else
fd = open(file,O_RDONLY);
#endif
}
if (fd < 0) return(-1);
if (!fd || (size <= 0)) size = 16384;
#ifdef VMS
BUF->rec = recsz;
#endif
BUF->fd = fd;
EOB = BEG = BUF->beg = (unsigned char *) MALLOC(size);
BUF->size = size;
return(read_file_dsc(1));
}
static int first_time_hack = 0; /* tru if reading file for first time */
/* if read something, return non zero (1) */
int read_file_dsc(int many)
{
int fd = BUF->fd, n = 0, i;
int dsize, size, passes = 0;
unsigned char *pos;
#ifdef VMS
int recsz = BUF->rec;
#endif
if (fd < 0) return (0);
if (fd == 0) dsize = 4 * 1024; else dsize = 16 * 1024;
while (many--)
{
if (passes++ == 1)
{
message("reading...", 0);
put_message();
}
if ((fd == 0) && (BEG != EOB))
{
size = (EOB - BEG) + dsize;
if (BUF->size > size) pos = BEG;
else
{
size = BUF->size + 16 * 1024;
pos = (unsigned char *) REALLOC(BEG, (unsigned) size);
BUF->size = size;
}
C_POS = pos + (C_POS - BEG);
if ((WIN != NULL) && (WIN->buf == BUF))
{
WIN->beg_pos = pos + (WIN->beg_pos - BEG);
WIN->curs_pos = pos + (WIN->curs_pos - BEG);
}
EOB = pos + (int) (EOB - BEG);
CURS_POS = pos + (CURS_POS - BEG);
BEG = pos;
}
pos = EOB;
n = 0;
#ifdef VMS
while ((i = read(fd, (char *) pos, recsz)) > 0)
#else
while ((i = read(fd, (char *) pos, dsize - n)) > 0 )
#endif
{
n += i;
pos += i;
if (n >= dsize) break;
}
if (n != 0) n = 1;
EOB = BUF->end = pos;
BUF->beg = BEG;
if ((i == 0) && (n < dsize))
{
close(fd);
BUF->fd = -1;
break;
}
}
if (first_time_hack)
{
/* This has to go here so that count_lines will work properly */
if (!MOST_B_OPT && !MOST_K_OPT)
for (pos = BEG; (pos < (BEG + 32)) && (pos < EOB); pos++)
{
if ((*pos == 0) || (*pos > 127)) MOST_B_OPT = 1;
}
}
NUM_LINES = count_lines(BEG,EOB);
if (passes > 1)
{
message("reading...done", 0);
put_message();
message(" ", 0);
}
return(n);
}
/* This routines makes sure line n is read in. */
void read_to_line(int n)
{
int dn;
if (BUF->fd == -1) return;
n = n + 2 * SCREEN_HEIGHT;
dn = n - NUM_LINES;
if (dn < 0) return;
/* dn is the number of lines to read.
Assume average of 40 bytes/line, then 40 * dn need read and we are
reading 16K at a time. Thus, */
dn = (40 * dn)/(16000);
if (dn == 0) dn = 1;
while ((BUF->fd != -1) && (n >= NUM_LINES)) read_file_dsc(dn);
}
int find_file(char *file)
{
Buffer *new_buf, *old_buf;
int n;
static char msg[300], *msgp;
new_buf = create_buffer(file);
old_buf = switch_to_buffer(new_buf);
first_time_hack = 1;
if (insert_file(file) < 0)
{
sprintf(msg, "%s failed to open.", file);
n = strlen(msg);
msgp = (char *) MALLOC((unsigned int) (n + 1));
strcpy(msgp, msg);
BUF->beg = (unsigned char *) msgp;
BUF->end = BUF->beg + n;
BUF->fd = -1;
NUM_LINES = 1;
}
first_time_hack = 0;
BEG = BUF->beg;
EOB = BUF->end;
C_POS = BEG;
C_LINE = 1;
COLUMN = 1;
return(1);
}
/* if the file is visible in a window, move to the window and return 1
else return 0 */
int file_visible(char *file)
{
Window *w;
w = WIN;
WIN = TOP_WIN;
do
{
if (!strcmp(WIN->buf->file,file))
{
set_window(WIN);
return(1);
}
WIN = WIN->next;
}
while (WIN != TOP_WIN);
WIN = w;
return(0);
}
void find_file_in_window(char *file)
{
if (file_visible(file)) return;
if (-1 == access(file,0)) /* does it exist? */
message("File not found.",1);
/* can we read it? */
/* else if (-1 == access(file,4))
message("File exists but not readable.",1); */
else
{
free_window_buffer();
(void) find_file(file);
window_buffer();
CURS_ROW = WIN->curs_line = 1;
CURS_POS = WIN->curs_pos = C_POS;
CURS_COL = WIN->curs_col = 1;
redraw_window();
update_status(0);
}
}
int next_file(int *j)
{
char mbuf[132], ch, *curr_file;
int i;
select_minibuffer();
tt_erase_line();
for (i = 0; i < SCREEN_WIDTH; i++) MINI_BUF[i] = ' ';
if (*j >= NUM_FILES) *j = 0;
curr_file = FILE_RING[*j];
sprintf(mbuf, "Next File (%d): %s\r", *j, curr_file);
send_string_to_term(mbuf);
while(ch = mbuf[i], ch != '\0') i++;
while(i < SCREEN_WIDTH) mbuf[i++] = ' ';
mbuf[i] = '\0';
strcpy((char *) MINI_BUF,mbuf);
while (1)
{
ch = getkey();
if (ch != '\033') break;
if (ch = getkey(), (ch != 'O') && (ch != '[')) continue;
if (ch = getkey(), (ch != 'A') && (ch != 'B')) continue;
if (ch == 'B')
{
if (*j == 0) *j = NUM_FILES;
(*j)--;
}
else /* ch == 'A' */
{
(*j)++;
if (*j == NUM_FILES) *j = 0;
}
curr_file = FILE_RING[*j];
sprintf(mbuf, "Next File (%d): %s", *j, curr_file);
i = strlen(mbuf);
while(i < SCREEN_WIDTH) mbuf[i++] = ' ';
mbuf[i] = '\0';
smart_puts((char *) mbuf, (char *) MINI_BUF, SCREEN_HEIGHT, 1);
curs_bol();
strcpy((char *) MINI_BUF,mbuf);
fflush(stdout);
}
tt_erase_line();
exit_minibuffer();
MINI_BUF[0] = 0;
(*j)++;
if ((ch == 'Q') || (ch == 'q')) return(-1);
find_file_in_window(curr_file);
return(0);
}
/* extracts directory from file string, returns false if no dir */
int head(char *file, char *dir)
{
int n;
(void) strcpy(dir,file);
n = strlen(file) - 1;
#ifdef VMS
while((n > -1) && ((file[n] != ']') || (file[n] != ':'))) n--;
#else
while((n > -1) && file[n] != '/') n--;
#endif
n++;
dir[n] = '\0';
return(n);
}
/* returns a pointer to the tail of file */
int tail(char *filed, char **filep)
{
int n;
n = strlen(filed) - 1;
#ifdef VMS
while((n > -1) && ((filed[n] != ']') || (filed[n] != ':'))) n--;
#else
while((n > -1) && (filed[n] != '/')) n--;
#endif
n++;
*filep = (filed + n);
return(n);
}
/* assume path is big enough to hold new expanded version */
int expand_path(char *path)
{
#ifndef VMS
int n;
#endif
/* really cheat here-- let system do it. The path must exist!! */
if (chdir(path))
{
message(path,1);
return(0);
}
else
{
get_cdir(path);
chdir(C_DIR);
#ifndef VMS
n = strlen(path);
if (path[n-1] == '/') return(1);
path[n++] = '/'; path[n] = 0;
#endif
}
return(1);
}
void cd()
{
char tmp_dir[80];
int n;
strcpy(tmp_dir,C_DIR);
if (read_from_minibuffer("cd",C_DIR) == -1) return;
if (!chdir(C_DIR))
{
get_cdir(C_DIR); /* expands ../ etc... */
n = strlen(C_DIR);
#ifndef VMS
if (C_DIR[n-1] == '/') return;
C_DIR[n++] = '/'; C_DIR[n] = 0;
#endif
return;
}
strcpy(C_DIR,tmp_dir);
chdir(C_DIR);
message("Unable to change directory.",1);
}
void user_get_file()
{
char path[255], file[255], *name;
#ifdef VMS
int i;
#endif
if (!head(WIN->buf->file,file))
strcpy(file,C_DIR);
if (read_from_minibuffer("Find File",file) == -1) return;
if (head(file,path))
{
expand_path(path);
tail(file,&name);
strcat(path,name);
name = path;
}
else name = file;
#ifdef VMS
for (i=0; i < strlen(name); i++) name[i] = toupper(name[i]);
#endif
find_file_in_window(name);
/*
** add to file ring if successful
*/
if (file_visible(name))
{
#ifdef VMS
FILE_RING[NUM_FILES] = (char*) MALLOC(strlen(name) + 1);
strcpy(FILE_RING[NUM_FILES++],name);
#else
FILE_RING[NUM_FILES++] = name;
#endif
}
}