home *** CD-ROM | disk | FTP | other *** search
- /*
- * Name: MicroGNUEmacs
- * Version: 2a
- * VAX/VMS file I/O.
- * Created: 05-Feb-86 decvax!decwrl!dec-rhea!dec-rex!conroy
- * Last edit: 1-Mar-88 sandra@cs.utah.edu
- *
- * Read and write ASCII files on VAX/VMS. All of the low level file
- * I/O knowledge is here. This uses RMS system calls directly because
- * the VAX C i/o functions are so slow.
- */
-
- #include "def.h"
- #include <rms.h>
- #define DEFAULT_READ_BUFFER_SIZE 1024
-
- struct FAB fab;
- struct RAB rab;
- struct XABFHC xab;
- char *inbuf;
- int instart, inend;
-
-
- /*
- * Open a file for reading. Also malloc's an input buffer that is big enough
- * to hold the longest line in the file.
- */
- ffropen(fn)
- char *fn;
- {
- int maxlen;
-
- fab = cc$rms_fab;
- rab = cc$rms_rab;
- xab = cc$rms_xabfhc;
- fab.fab$l_fna = fn;
- fab.fab$b_fns = strlen(fn);
- fab.fab$l_xab = &xab;
- rab.rab$l_fab = &fab;
- rab.rab$w_isi = 0;
- if (SYS$OPEN (&fab, 0, 0) == RMS$_NORMAL) {
- SYS$CONNECT (&rab, 0, 0);
- if (xab.xab$w_lrl == 0)
- maxlen = DEFAULT_READ_BUFFER_SIZE;
- else
- maxlen = xab.xab$w_lrl;
- inbuf = malloc(maxlen);
- instart = 0;
- inend = 0;
- rab.rab$l_ubf = inbuf;
- rab.rab$w_usz = maxlen;
- return (FIOSUC);
- }
- else
- return (FIOFNF);
- }
-
- /*
- * Open a file for writing.
- * Return TRUE if all is well, and
- * FALSE on error (cannot create).
- */
- ffwopen(fn)
- char *fn;
- {
- int status;
-
- fab = cc$rms_fab;
- rab = cc$rms_rab;
- fab.fab$l_fna = fn;
- fab.fab$b_fns = strlen(fn);
- fab.fab$b_rat = FAB$M_CR;
- fab.fab$b_rfm = FAB$C_VAR;
- rab.rab$l_fab = &fab;
- rab.rab$w_isi = 0;
- status = SYS$CREATE (&fab, 0, 0);
- switch (status) {
-
- case RMS$_NORMAL:
- case RMS$_FILEPURGED:
- SYS$CONNECT (&rab, 0, 0);
- inbuf = NULL;
- return (FIOSUC);
-
- default:
- ewprintf("Cannot open file for writing STS=%d, STV=%d",
- fab.fab$l_sts, fab.fab$l_stv);
- return (FIOERR);
- }
- }
-
- /*
- * Close a file.
- */
- ffclose()
- {
- if (inbuf)
- free(inbuf);
- if (SYS$CLOSE(&fab, 0, 0) == RMS$_NORMAL)
- return (FIOSUC);
- else
- return (FIOERR);
- }
-
- /*
- * Write a buffer to the already opened file. bp points to the
- * buffer. Return the status.
- * This doesn't write out the last line of the buffer unless it is
- * non-empty, to prevent VMS from putting an extra newline at the
- * end of the file.
- */
-
- ffputbuf(bp)
- BUFFER *bp;
- {
- register LINE *lp;
- register LINE *lpend;
- int status;
-
- lpend = bp->b_linep;
- lp = lforw(lpend);
- while (! ((lp == lpend) || ((lforw(lp) == lpend) && (llength(lp) == 0)))) {
- rab.rab$l_rbf = <ext(lp)[0];
- rab.rab$w_rsz = llength(lp);
- if ((status = SYS$PUT (&rab, 0, 0)) != RMS$_NORMAL) {
- ewprintf("Write I/O error, VMS status code %d", status);
- return(FIOERR);
- }
- lp = lforw(lp);
- }
- return FIOSUC;
- }
-
- /*
- * Read a line from a file, and store the bytes in the
- * supplied buffer. Stop on end of file or end of line.
- * Returns an extra newline on FIOEOF.
- *
- */
-
- ffgetline(buf, nbuf, nbytes)
- register char *buf;
- register int nbuf;
- register int *nbytes;
-
- { register int status;
- register int i;
-
-
- /* Load the input buffer if it's empty. */
-
- if (instart >= inend) {
- status = SYS$GET (&rab, 0, 0);
- if (status == RMS$_EOF) {
- *nbytes = 0;
- return FIOEOF;
- }
- else if (status != RMS$_NORMAL) {
- ewprintf("File read error, VMS status code %d", status);
- return FIOERR;
- }
- else {
- instart = 0;
- inend = rab.rab$w_rsz;
- }
- }
-
- /* Copy contents of the input buffer */
-
- *nbytes = inend - instart;
- if (*nbytes > nbuf) *nbytes = nbuf;
- for (i=0; i<*nbytes; i++)
- buf[i] = inbuf[instart++];
- if (instart < inend)
- return FIOLONG;
- else
- return FIOSUC;
-
- }
-
- #ifndef NO_BACKUP
- /*
- * VMS has version numbers, so there is no need for
- * MicroEMACS to bother making its own flavour of
- * backup copy. Return TRUE so the caller doesn't quit.
- */
- fbackupfile(fname)
- char *fname;
- {
- return (TRUE);
- }
- #endif
-
- /*
- * The string "fn" is a file name. Canonicalize it by making RMS
- * do the dirty work, then lowercase it.
- */
- char *adjustname(fn)
- char *fn;
- {
- register char *cp;
- #ifndef NO_DIR
- char *fullname, *fparse(), *strrchr();
- static char name[NFILEN];
-
- if (fullname = fparse(fn, NULL, NULL, NULL)) {
- strncpy(name, fullname, NFILEN);
- fn = name;
- free(fullname); /* fparse malloc()'s the name */
- }
- #endif
- for (cp = fn; *cp ; cp++)
- if (ISUPPER(*cp))
- *cp = *cp - 'A' + 'a';
- return fn;
- }
-
- /*
- * Fn1 and Fn2 are two file names. Return 0 if they represent the
- * same file.
- * Both arguments have already gone through adjustname(), so just do
- * strcmp() here.
- */
- fncmp(fn1,fn2)
- char *fn1,*fn2;
- {
- return strcmp(fn1,fn2);
- }
-
- #ifndef NO_STARTUP
- #include <file.h>
- /*
- * Find the user's startup file, and return its name.
- */
- char *
- startupfile(suffix)
- char *suffix;
- {
- static char file[NFILEN];
-
- (VOID) strcpy(file, "SYS$LOGIN:.MG");
- if (suffix) {
- strcat(file,"-");
- strcat(file,suffix);
- }
- if (access(file, O_RDONLY ) == 0) return file;
- return NULL;
- }
- #endif
-
- #ifndef NO_DIR
- #include <descrip.h>
- #include <ssdef.h>
-
- /*
- * Get current working directory. Path had best be rather big
- * (at least 400 characters long...)
- */
-
- $DESCRIPTOR(sys_disk,"SYS$DISK");
-
- char *getwd(path)
- char path[];
- {
- struct dsc$descriptor devdsc, dirdsc;
- char tempdev[512], tempdir[512];
- int status, templen;
- short devlen, dirlen;
-
- /* translate the logical name SYS$DISK */
-
- devdsc.dsc$a_pointer = tempdev;
- devdsc.dsc$w_length = sizeof(tempdev) - 1;
- devdsc.dsc$b_dtype = DSC$K_DTYPE_T;
- devdsc.dsc$b_class = DSC$K_CLASS_S;
-
- status = LIB$SYS_TRNLOG(&sys_disk, &devlen, &devdsc);
- if (status!=SS$_NORMAL && status!=SS$_NOTRAN)
- panic("getwd: can't translate SYS$DISK");
-
- /* Append the current default directory using SYS$SETDDIR() */
-
- dirdsc.dsc$b_dtype = DSC$K_DTYPE_T;
- dirdsc.dsc$b_class = DSC$K_CLASS_S;
- dirdsc.dsc$a_pointer = tempdir;
- dirdsc.dsc$w_length = sizeof(tempdir) - 1;
-
- status = SYS$SETDDIR(0L, &dirlen, &dirdsc);
- if (status != RMS$_NORMAL)
- panic("getwd: can't get current directory!");
-
- bcopy(tempdev,path,devlen);
- bcopy(tempdir,path+devlen,dirlen);
- path[devlen + dirlen] = '\0';
- return path;
- }
- #endif
-