home *** CD-ROM | disk | FTP | other *** search
- /*
- * Name: Mg 2a
- * MSDOS file I/O (TurboC 1.5)
- */
- #include "def.h"
- #include <stdio.h>
-
- #ifdef MSC
- #include <dos.h>
- #endif /* MSC */
-
- #ifndef F_OK
- #define F_OK 0
- #define X_OK 1
- #define W_OK 2
- #define R_OK 4
- #endif
-
- #ifndef NO_DIR
- extern char *wdir;
- #endif
-
- static FILE *ffp;
-
- /*
- * Open a file for reading.
- */
- ffropen(fn)
- char *fn;
- {
- if ((ffp=fopen(fn, "rb")) == NULL)
- return (FIOFNF);
- return (FIOSUC);
- }
-
- /*
- * Open a file for writing.
- * Return TRUE if all is well, and
- * FALSE on error (cannot create).
- */
- ffwopen(fn)
- char *fn;
- {
- if ((ffp=fopen(fn, "wb")) == NULL) {
- ewprintf("Cannot open file for writing");
- return (FIOERR);
- }
- return (FIOSUC);
- }
-
- /*
- * Close a file.
- * Should look at the status.
- */
- ffclose()
- {
- (VOID) fclose(ffp);
- return (FIOSUC);
- }
-
- /*
- * Write a line to the already
- * opened file. The "buf" points to the
- * buffer, and the "nbuf" is its length, less
- * the free newline. Return the status.
- * Check only at the newline.
- */
- ffputline(buf, nbuf)
- register char buf[];
- {
- register int i;
-
- for (i=0; i<nbuf; ++i)
- putc(buf[i]&0xFF, ffp);
- putc('\r', ffp); /* MSDOS wants \r\n line seperators */
- putc('\n', ffp);
- if (ferror(ffp) != FALSE) {
- ewprintf("Write I/O error");
- return (FIOERR);
- }
- return (FIOSUC);
- }
-
- /*
- * Write a buffer to the already
- * opened file. bp points to the
- * buffer. Return the status.
- * Check only at the newline and
- * end of buffer.
- */
- ffputbuf(bp)
- BUFFER *bp;
- {
- register char *cp;
- register char *cpend;
- register LINE *lp;
- register LINE *lpend;
-
- lpend = bp->b_linep;
- lp = lforw(lpend);
- do {
- cp = <ext(lp)[0]; /* begining of line */
- cpend = &cp[llength(lp)]; /* end of line */
- while(cp != cpend) {
- putc(*cp, ffp);
- cp++; /* putc may evalualte arguments more than once */
- }
- lp = lforw(lp);
- if(lp == lpend) break; /* no implied newline on last line */
- putc('\r', ffp); /* MSDOS wants \r\n line seperators */
- putc('\n', ffp);
- } while(!ferror(ffp));
- if(ferror(ffp)) {
- ewprintf("Write I/O error");
- return FIOERR;
- }
- 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. Don't get upset by files that don't have an end of
- * line on the last line; this seem to be common on CP/M-86 and
- * MS-DOS. Delete any CR followed by a NL: This is the normal
- * format for MS_DOS files, but also occurs when files are transferred
- * from VMS or MS-DOS to Unix.
- */
- ffgetline(buf, nbuf, nbytes)
- register char buf[];
- register int *nbytes;
- {
- register int c;
- register int i;
-
- i = 0;
- for (;;) {
- c = getc(ffp);
- rescan:
- if (c == '\r') { /* Delete any non-stray */
- c = getc(ffp); /* carriage returns. */
- if (c != '\n') {
- buf[i++] = '\r';
- if (i >= nbuf) return FIOLONG;
- goto rescan;
- }
- }
- if (c==EOF || c=='\n') /* End of line. */
- break;
- buf[i++] = c;
- if (i >= nbuf) return FIOLONG;
- }
- if (c == EOF && ferror(ffp) != FALSE) {
- ewprintf("File read error");
- return FIOERR;
- }
- *nbytes = i;
- return c==EOF ? FIOEOF : FIOSUC;
- }
-
- #ifndef NO_BACKUP
- /*
- * Rename the file "fname" into a backup copy.
- * On Unix the backup has the same name as the
- * original file, with a "~" on the end - unfortunately
- * this does not map well to MS-DOS - the old .bak convention
- * is used.
- */
- fbackupfile(fname)
- char *fname;
- {
- register char *nname, *ptr;
- char *strchr();
-
- if ((nname=malloc(strlen(fname)+3+1)) == NULL)
- return (ABORT);
- (void) strcpy(nname, fname);
- if ((ptr = strchr(nname, '.')) != 0)
- strcpy(ptr, ".bak");
- else
- strcat(ptr, ".bak");
-
- if (strcmp(fname, nname) == 0) {
- free(nname);
- return FALSE;
- }
-
- (void) unlink(nname); /* Ignore errors. */
- (void) rename(fname, nname);
- free(nname);
- return (TRUE);
- }
- #endif
-
- /*
- * The string "fn" is a file name.
- * convert all filenames to lower case, and convert all '\\' characters
- * to forward slashes. This is simply my preference, uppercase and
- * back slashes are also viable.
- */
- /*ARGSUSED*/
- adjustmsdos(fn)
- register char *fn;
- {
- register char c;
-
- while ((c = *fn) != '0') {
- if (ISUPPER(c))
- *fn = TOLOWER(c);
- if (c=='/')
- *fn = '\\';
- ++fn;
- }
- }
-
-
-
- #ifndef NO_STARTUP
- #define STARTUPNAME ".mg"
- /*
- * find the users startup file, and return it's name. Check for
- * if MGSTARTUP is defined, then use that. Otherwise, look
- * for .mg in the current directory, then in the root directory.
- */
- char *
- startupfile()
- {
- register char *file;
- static char temp[NFILEN];
- char *getenv();
-
- if ((file = getenv("MGSTARTUP")) != NULL )
- {
- if (access(file, F_OK) == 0)
- return file;
- return NULL;
- }
- if (access (STARTUPNAME, F_OK) == 0)
- return STARTUPNAME;
- strcpy(temp, "/");
- strcat(temp, STARTUPNAME);
- if (access (temp, F_OK) == 0)
- return temp;
- return NULL;
- }
- #endif
-
- /*******************************************************************/
- /* new stuff between release 1a and 2a */
- /*******************************************************************/
-
- /* convert all filenames to a canonical format, which in the case of
- * MSDOS is X:/currentdir/filename. Note that each drive letter has
- * it's OWN current directory, so if the user specifies a drive letter,
- * we use that drive's current directory, not it's root.
- */
-
- /* MSC doesn't have getdrive and getcurdir routines; simulate them.
- * They are both pretty gross. Blame Microsoft */
-
- #ifdef MSC
- unsigned getdisk()
- {
- unsigned currentdrive;
-
- _dos_getdrive(¤tdrive);
- return currentdrive-1;
- }
-
- void getcurdir(unsigned drivenumber, char *buf)
- {
- unsigned currentdrive = getdisk()+1;
- unsigned number_of_drives; /* unused */
- static char bufr[NFILEN];
-
- _dos_setdrive(drivenumber, &number_of_drives);
- getcwd(&bufr[0], NFILEN-1);
- _dos_setdrive(currentdrive, &number_of_drives);
- strcpy(buf, &bufr[3]);
- }
- #endif
-
- char *adjustname(fn)
- register char *fn;
- {
- register char *cp;
- static char fnb[NFILEN];
- struct passwd *pwent;
-
- cp = fnb;
- /* handle A:foo\bar */
- if (fn[0] && fn[1] == ':') {
- *cp++ = *fn++;
- *cp++ = *fn++;
- *cp = '\0';
- adjustmsdos(fnb); /* force case to lower */
- if (*fn != '/' && *fn != '\\') {
- *cp++ = '\\';
- getcurdir(fnb[0]-'a'+1, cp);
- cp = fnb + strlen(fnb);
- }
- else
- *cp++ = *fn++;
- }
- /* handle \foo\bar */
- else if (*fn == '/' || *fn == '\\') {
- *cp++ = (char) (getdisk() + 'a');
- *cp++ = ':';
- *cp++ = *fn++;
- }
- else {
- strcpy(fnb, wdir);
- cp = fnb + strlen(fnb);
- }
-
- if(cp != fnb && cp[-1] != '/' && cp[-1] != '\\') *cp++ = '\\';
-
- /* at this point, we should have a drive, and at least a single */
- /* slash. Now copy over the rest of the filename, while handling */
- /* certain pathalogical cases */
-
- /* convert "//" to "/", "/./" to "/", and "/x/../" to "/" */
- while(*fn) {
- switch(*fn) {
- case '.':
- switch(fn[1]) {
- case '\0':
- *--cp = '\0';
- adjustmsdos(fnb);
- return fnb;
- case '/':
- case '\\':
- fn += 2;
- continue;
- case '.':
- if(fn[2]=='/' || fn[2]=='\\' || fn[2] == '\0') {
- --cp;
- while(cp > fnb && *--cp != '/' && *cp != '\\')
- ;
- if (cp==fnb) cp += 2;
- ++cp;
- if(fn[2]=='\0') {
- *--cp = '\0';
- adjustmsdos(fnb);
- return fnb;
- }
- fn += 3;
- continue;
- }
- break;
- default:
- break;
- }
- break;
- case '/':
- case '\\':
- fn++;
- continue;
- default:
- break;
- }
- while(*fn && (*cp++ = *fn++) != '/' && fn[-1] != '\\')
- ;
- }
- if (cp != fnb + 3 && cp[-1]=='\\') --cp;
- *cp = '\0';
- adjustmsdos(fnb);
- return fnb;
- }
-
- #ifndef NO_DIRED
- #include "kbd.h"
- #define DIRFILE "_dirlist_.$$$"
-
- BUFFER *dired_(dirname)
- char *dirname;
- {
- register BUFFER *bp;
- char line[256];
- BUFFER *findbuffer();
- char *strncpy();
- int i;
-
- if((dirname = adjustname(dirname)) == NULL) {
- ewprintf("Bad directory name");
- return NULL;
- }
- if((bp = findbuffer(dirname)) == NULL) {
- ewprintf("Could not create buffer");
- return NULL;
- }
- if(bclear(bp) != TRUE) return FALSE;
- (VOID) strcpy(line, "dir ");
- (VOID) strcat(line, dirname);
- (VOID) strcat(line, " > ");
- (VOID) strcat(line, DIRFILE);
- system(line);
- if (ffropen(DIRFILE) != FIOSUC) {
- ewprintf("Can't open temporary dir file");
- return NULL;
- }
- line[0] = line[1] = ' ';
- if (ffgetline(&line[2], sizeof(line)-3, &i) != FIOSUC) {
- ffclose();
- (void)unlink(DIRFILE);
- ewprintf("No such directory: `%s'", dirname);
- return NULL;
- }
- while (ffgetline(&line[2], sizeof(line)-3, &i) == FIOSUC) {
- line[i+2] = '\0';
- (VOID) addline(bp, line);
- }
- ffclose();
- (void)unlink(DIRFILE);
-
- bp->b_dotp = lforw(bp->b_linep); /* go to first line */
- (VOID) strncpy(bp->b_fname, dirname, NFILEN);
- if((bp->b_modes[0] = name_mode("dired")) == NULL) {
- bp->b_modes[0] = &map_table[0];
- ewprintf("Could not find mode dired");
- return NULL;
- }
- bp->b_nmodes = 0;
- return bp;
- }
-
- /* this is really ugly, but then so was the UNIX version! */
- #define BASENAME 2
- #define EXT 11
- #define DIR 15
- d_makename(lp, fn)
- register LINE *lp;
- register char *fn;
- {
- register char *cp;
- register char *last;
- int len;
- extern char *strchr();
-
- if(llength(lp) != 41) return ABORT;
- if(lgetc(lp,BASENAME) == ' ') return ABORT;
- if(lgetc(lp,EXT-1) != ' ') return ABORT;
- (VOID) strcpy(fn, curbp->b_fname);
- cp = fn + strlen(fn);
- if ((cp[-1] != '\\') && (cp[-1] != '/')) /* append '/' if needed */
- *cp++ = '\\';
- if ((last = strchr(lp->l_text+BASENAME, ' ')) == 0) return ABORT;
- len = last - (lp->l_text+BASENAME);
- bcopy(lp->l_text+BASENAME, cp, len);
- cp += len;
- if ((last = strchr(lp->l_text+EXT, ' ')) == 0) return ABORT;
- len = last - (lp->l_text+EXT);
- if (len != 0) {
- *cp++ = '.';
- bcopy(lp->l_text+EXT, cp, len);
- }
- cp[len] = '\0';
- return (strncmp(lp->l_text+DIR, "<DIR>", 5) == 0);
- }
-
- /* sorry, this is a hack - jpn */
- /* I should probably fix this */
- copy(frname, toname)
- char *frname, *toname;
- {
- char buffer[512];
- int pid;
- int status;
- char cmdbuf[80];
-
- sprintf(cmdbuf, "Copy %s %s", frname, toname);
- system(cmdbuf);
- return TRUE;
- }
-
- unlinkdir(f)
- char *f;
- {
- return (rmdir(f));
- }
-
- #endif /* NO_DIRED */
-