home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 10 / Fresh_Fish_10_2352.bin / useful / util / edit / mg / src.lzh / amiga / fileio.c < prev    next >
C/C++ Source or Header  |  1990-05-23  |  14KB  |  638 lines

  1. /*
  2.  * Name:    MG 2a401 Commodore Amiga file I/O. Last edit:    05-May-88
  3.  * swalton@solar.stanford.edu Next-to-Last edit:    16-Dec-87
  4.  * mic@emx.utexas.edu Created:    23-Jul-86 mic@emx.utexas.edu
  5.  * 
  6.  * Read and write ASCII files. All of the low level file I/O knowledge is here.
  7.  * Uses AmigaDOS standard I/O and does its own dynamic buffering; this seems
  8.  * to save about 2K worth of space in the executable image.
  9.  */
  10.  
  11. #undef        LATTICE
  12. #undef        MANX
  13. #include    "compiler.h"
  14. #include    "no_backup.h"
  15. #include    "no_startup.h"
  16. #include    "no_dir.h"
  17. #include    "no_dired.h"
  18.  
  19. #ifdef        LATTICE
  20. #include    <stdlib.h>
  21. #include    <string.h>
  22. #include    <exec/types.h>
  23. #endif
  24. #include    "use_arp.h"
  25. #include    "foob.h"
  26. #include    <exec/memory.h>
  27. #include    <libraries/dos.h>
  28. #include    <libraries/dosextens.h>
  29. #ifdef        USE_ARP
  30. #include    <arpfunctions.h>
  31. #include    <libraries/arpbase.h>
  32. #else
  33. #define FCHARS    32L
  34. #endif
  35.  
  36. #ifdef LATTICE
  37. #include <proto/all.h>
  38. #else
  39. #include    <functions.h>
  40. #endif
  41. #undef    TRUE
  42. #undef    FALSE
  43. #include    "def.h"
  44. #include    "line.h"
  45. #include    "buffer.h"
  46.  
  47. #ifdef ANSI
  48. #undef EOF
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #include <string.h>
  52. #endif
  53.  
  54. #ifndef    NO_PROTO
  55. char           *mktemp PROTO((char *));
  56. #endif
  57.  
  58. #ifdef    LATTICE
  59. #undef LATTICE
  60. #include <dos.h>
  61. #define isdirectory(x)    (getfa(x) == 1)
  62. #endif
  63.  
  64.  
  65. #define    NIOBUF            4096
  66.  
  67. static VOID FlushBuf PROTO((VOID));
  68.  
  69. static BPTR     ffh = 0;
  70. static UBYTE   *iobuf;
  71. static int      ibufo, niobuf;
  72. static LONG     iostat, access_mode;
  73. #ifdef    MANX
  74. extern char    *strncpy(), *strncat(), *index(), *rindex();
  75. #endif
  76.  
  77. #ifdef    LATTICE
  78. static void     TackOn(char *path, char *file);
  79. #define    index    strchr
  80. #define rindex    strrchr
  81. #endif
  82.  
  83. #define    getch()        (ibufo == niobuf) ? FillBuf() : iobuf[ibufo++]
  84. #define putch(c)    {if (niobuf == NIOBUF) FlushBuf(); iobuf[niobuf++] = c;}
  85.  
  86. /*
  87.  * Open the Emacs internal file for reading.
  88.  */
  89. ffropen(fn)
  90.     char           *fn;
  91. {
  92.     if ((iobuf = AllocMem((ULONG) NIOBUF, 0L)) == NULL)
  93.         return (FIOERR);
  94.  
  95.     if ((ffh = Open(fn, access_mode = MODE_OLDFILE)) == 0L) {
  96.         FreeMem(iobuf, (ULONG) NIOBUF);
  97.         return (FIOFNF);
  98.     }
  99.     ibufo = niobuf = 0;
  100.     return (FIOSUC);
  101. }
  102.  
  103. /*
  104.  * Open a file for writing.  Return TRUE if all is well, and FALSE on error
  105.  * (cannot create).
  106.  */
  107.  
  108. ffwopen(fn)
  109.     char           *fn;
  110. {
  111.     if ((iobuf = AllocMem((ULONG) NIOBUF, 0L)) == NULL)
  112.         return (FIOERR);
  113.     if ((ffh = Open(fn, access_mode = MODE_NEWFILE)) == 0L) {
  114.         ewprintf("Cannot open file for writing");
  115.         FreeMem(iobuf, (ULONG) NIOBUF);
  116.         return (FIOERR);
  117.     }
  118.     niobuf = 0;
  119.     iostat = NIOBUF;    /* pretend we wrote out a full buffer last
  120.                  * time */
  121.     return (FIOSUC);
  122. }
  123.  
  124. /*
  125.  * Close a file, flushing the output buffer.  Should look at the status.
  126.  */
  127. ffclose()
  128. {
  129.     if (access_mode == MODE_NEWFILE)
  130.         FlushBuf();
  131.     if (ffh)
  132.         (void) Close(ffh);
  133.     if (iobuf)
  134.         FreeMem(iobuf, (ULONG) NIOBUF);
  135.     return (FIOSUC);
  136. }
  137.  
  138. /*
  139.  * Write a buffer to the already opened file. bp points to the buffer. Return
  140.  * the status. Check only at the newline and end of buffer.
  141.  */
  142. ffputbuf(bp)
  143.     struct buffer  *bp;
  144. {
  145.     register char  *cp;
  146.     register char  *cpend;
  147.     register struct line *lp;
  148.     register struct line *lpend;
  149.  
  150.     lpend = bp->b_linep;
  151.     lp = lforw(lpend);
  152.     do {
  153.         cp = <ext(lp)[0];    /* begining of line     */
  154.         cpend = &cp[llength(lp)];    /* end of line         */
  155.         while (cp != cpend)
  156.             putch(*(cp++));    /* putch only evalutes its arg once */
  157.         lp = lforw(lp);
  158.         if (lp == lpend)
  159.             break;    /* no implied newline on last line */
  160.         putch('\n');
  161.     } while (iostat > 0L);
  162.  
  163.     if (iostat == -1L) {
  164.         ewprintf("Write I/O error");
  165.         return FIOERR;
  166.     }
  167.     return FIOSUC;
  168. }
  169.  
  170. /*
  171.  * Read a line from a file, and store the bytes in the supplied buffer. Stop
  172.  * on end of file or end of line.  When FIOEOF is returned, there is a valid
  173.  * line of data without the normally implied \n.
  174.  */
  175. ffgetline(buf, nbuf, nbytes)
  176.     register char  *buf;
  177.     register int    nbuf;
  178.     register int   *nbytes;
  179. {
  180.     register int    c;
  181.     register int    i;
  182.  
  183.     i = 0;
  184.     while ((c = getch()) != EOF && (c & 0xFF) != '\n') {
  185.         buf[i++] = c;
  186.         if (i >= nbuf)
  187.             return FIOLONG;
  188.     }
  189.     if (c == EOF && (iostat == -1L)) {
  190.         ewprintf("File read error");
  191.         return FIOERR;
  192.     }
  193.     *nbytes = i;
  194.     return c == EOF ? FIOEOF : FIOSUC;
  195. }
  196.  
  197. #ifndef    NO_BACKUP
  198. #include "backup_suffix.h"
  199. /*
  200.  * Rename the current file into a backup copy, possibly after deleting the
  201.  * original file.
  202.  */
  203. fbackupfile(fname)
  204.     char           *fname;
  205. {
  206.     BPTR            twiddle, lock;
  207.     char            buffer[NFILEN];
  208.  
  209.     if (!fname)
  210.         return FALSE;
  211.     (void) strncpy(buffer, fname, NFILEN - 1);
  212.     (void) strcat(buffer, BACKUP_SUFFIX);
  213.  
  214.     lock = Lock(fname, (ULONG) EXCLUSIVE_LOCK);    /* does file exist?     */
  215.     if (!lock)
  216.         return (FALSE);    /* nope, return error     */
  217.  
  218.     twiddle = Lock(buffer, (ULONG) EXCLUSIVE_LOCK);
  219.     if (twiddle) {        /* delete old backup     */
  220.         UnLock(twiddle);/* let it go         */
  221.         if (!DeleteFile(buffer)) {
  222.             UnLock(lock);
  223.             return (FALSE);
  224.         }
  225.         twiddle = NULL;
  226.     }
  227.     /*
  228.      * rename file to backup name (after unlocking the file)
  229.      */
  230.     UnLock(lock);
  231.     return (int) Rename(fname, buffer);
  232. }
  233. #endif                /* NO_BACKUP */
  234.  
  235. #ifdef FOOB
  236. #define    DEFAULT_FOOB    (0L)
  237. FOOB
  238. getfoob(fname)
  239.     char           *fname;
  240. {
  241.     struct FileInfoBlock *fib;
  242.     BPTR            lock;
  243.     FOOB            out;
  244.  
  245.     if (fname == NULL)
  246.         return DEFAULT_FOOB;
  247.     if ((lock = Lock(fname, ACCESS_READ)) == NULL)    /* New file? */
  248.         return DEFAULT_FOOB;
  249.  
  250.     if ((fib = (struct FileInfoBlock *)
  251.          AllocMem(sizeof(struct FileInfoBlock), 0L)) == NULL) {
  252.         ewprintf("Couldn't get %d bytes", sizeof(struct FileInfoBlock));
  253.         UnLock(lock);
  254.         return DEFAULT_FOOB;
  255.     }
  256.     if (Examine(lock, fib))
  257.         out = fib->fib_Protection;
  258.     else {
  259.         ewprintf("Couldn't get protection bits for %s", fname);
  260.         out = DEFAULT_FOOB;
  261.     }
  262.  
  263.     UnLock(lock);
  264.     FreeMem(fib, sizeof(struct FileInfoBlock));
  265.     return out;
  266.  
  267. }
  268.  
  269. void
  270. putfoob(name, mask)
  271.     char           *name;
  272.     FOOB            mask;
  273. {
  274.     SetProtection(name, mask & ~FIBF_ARCHIVE);
  275. }
  276. #endif
  277.  
  278. #ifndef    NO_STARTUP
  279. /*
  280.  * Return name of user's startup file.  On Amiga, make it .mg in the current
  281.  * directory, then s:mg-startup
  282.  */
  283.  
  284. static char     startname[] = ".mg";
  285. static char     altstartname[] = "s:mg-startup";
  286.  
  287. char           *
  288. startupfile()
  289. {
  290.     BPTR            lock;
  291.  
  292.     if (lock = Lock(startname, (ULONG) SHARED_LOCK)) {
  293.         UnLock(lock);
  294.         return (startname);
  295.     }
  296.     if (lock = Lock(altstartname, (ULONG) SHARED_LOCK)) {    /* alternate */
  297.         UnLock(lock);
  298.         return (altstartname);
  299.     }
  300.     return (NULL);
  301. }
  302. #endif                /* NO_STARTUP */
  303.  
  304. /*
  305.  * The string "fn" is a file name. Perform any required name adjustments,
  306.  * including conversion to a fully qualified path if NO_DIR isn't defined.
  307.  */
  308.  
  309. extern char    *MyDirName;
  310.  
  311. char           *
  312. adjustname(fn)
  313.     register char  *fn;
  314. {
  315. #ifndef NO_DIR
  316.     static char     fnb[MAXPATH];
  317.     BPTR            lock;
  318.     unsigned long   PathName();
  319.     void            TackOn();
  320.     char           *dup, *p;
  321.  
  322.     if (!fn)
  323.         return fn;
  324.     if (!index(fn, ':')) {    /* no device         */
  325.         strcpy(fnb, MyDirName);
  326.         TackOn(fnb, fn);
  327.         if (!index(fn, '/'))    /* completely bare name */
  328.             return fnb;
  329.     } else
  330.         strcpy(fnb, fn);
  331.     /*
  332.      * Else fn has some path components in it.  We try to PathName the
  333.      * whole thing first, but since the file specified by fn may not
  334.      * exist, we PathName the leading part and TackOn the trailing part
  335.      * if it doesn't.
  336.      */
  337.     if (lock = Lock(fnb, SHARED_LOCK)) {
  338.         if (PathName(lock, fnb, (long) MAXPATH) != 0) {
  339.             UnLock(lock);
  340.             return fnb;
  341.         }
  342.         ewprintf("adjustname: PathName() failed!");
  343.         UnLock(lock);
  344.         return fn;
  345.     }
  346.     if (!(p = rindex(fnb, '/')))
  347.         p = index(fnb, ':');
  348.     p++;
  349.     strcpy((dup = malloc(strlen(p) + 1)), p);
  350.     *p = '\0';
  351.     if (lock = Lock(fnb, SHARED_LOCK)) {
  352.         if (PathName(lock, fnb, (long) MAXPATH) != 0) {
  353.             UnLock(lock);
  354.             TackOn(fnb, dup);
  355.             free(dup);
  356.             return fnb;
  357.         }
  358.         ewprintf("adjustname: PathName() failed!");
  359.         UnLock(lock);
  360.     }
  361.     free(dup);
  362. #endif
  363.     return fn;        /* if all else fails     */
  364. }
  365.  
  366. /*
  367.  * Functions to read/write into the I/O buffer
  368.  */
  369.  
  370. VOID 
  371. FlushBuf()
  372. {
  373.     if (niobuf > 0) {
  374.         iostat = Write(ffh, iobuf, (long) niobuf);
  375.         niobuf = 0;
  376.     }
  377. }
  378.  
  379. /*
  380.  * Fill up the input buffer and return the first character in it.
  381.  */
  382. int 
  383. FillBuf()
  384. {
  385.     if ((iostat = Read(ffh, iobuf, (long) NIOBUF)) <= 0L)
  386.         return (EOF);
  387.     ibufo = 0;
  388.     niobuf = (int) iostat;
  389.     return (int) (iobu