home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 198_01 / file.c < prev    next >
C/C++ Source or Header  |  1990-01-23  |  23KB  |  769 lines

  1. /*    FILE.C:   for MicroEMACS
  2.  
  3.     The routines in this file handle the reading, writing
  4.     and lookup of disk files.  All of details about the
  5.     reading and writing of the disk are in "fileio.c".
  6.  
  7. */
  8.  
  9. #include        <stdio.h>
  10. #include    "estruct.h"
  11. #include        "edef.h"
  12.  
  13. /*
  14.  * Read a file into the current
  15.  * buffer. This is really easy; all you do it
  16.  * find the name of the file, and call the standard
  17.  * "read a file into the current buffer" code.
  18.  * Bound to "C-X C-R".
  19.  */
  20. fileread(f, n)
  21. {
  22.         register int    s;
  23.         char fname[NFILEN];
  24.  
  25.     if (restflag)        /* don't allow this command if restricted */
  26.         return(resterr());
  27.         if ((s=mlreply("Read file: ", fname, NFILEN)) != TRUE)
  28.                 return(s);
  29.         return(readin(fname, TRUE, FALSE));
  30. }
  31.  
  32. /*
  33.  * Insert a file into the current
  34.  * buffer. This is really easy; all you do it
  35.  * find the name of the file, and call the standard
  36.  * "insert a file into the current buffer" code.
  37.  * Bound to "C-X C-I".
  38.  */
  39. insfile(f, n)
  40. {
  41.         register int    s;
  42.         char fname[NFILEN];
  43.  
  44.     if (restflag)        /* don't allow this command if restricted */
  45.         return(resterr());
  46.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  47.         return(rdonly());    /* we are in read only mode    */
  48.         if ((s=mlreply("Insert file: ", fname, NFILEN)) != TRUE)
  49.                 return(s);
  50.         return(ifile(fname));
  51. }
  52.  
  53. /*
  54.  * Select a file for editing.
  55.  * Look around to see if you can find the
  56.  * fine in another buffer; if you can find it
  57.  * just switch to the buffer. If you cannot find
  58.  * the file, create a new buffer, read in the
  59.  * text, and switch to the new buffer.
  60.  * Bound to C-X C-F.
  61.  */
  62. filefind(f, n)
  63. {
  64.         char fname[NFILEN];    /* file user wishes to find */
  65.         register int s;        /* status return */
  66.  
  67.     if (restflag)        /* don't allow this command if restricted */
  68.         return(resterr());
  69.         if ((s=mlreply("Find file: ", fname, NFILEN)) != TRUE)
  70.                 return(s);
  71.     return(getfile(fname, TRUE));
  72. }
  73.  
  74. #if    DECEDT
  75. /*
  76.  * Select a file for editing and insert it into another window.
  77.  * If there is only one window, split it, otherwise pick a non-current window.
  78.  * Look around to see if you can find the
  79.  * file in another buffer; if you can find it
  80.  * just switch to the buffer. If you cannot find
  81.  * the file, create a new buffer, read in the
  82.  * text, and switch to the new buffer.
  83.  * Bound to C-X 4.
  84.  */
  85. filewfind(f, n)
  86. {
  87.         char fname[NFILEN];    /* file user wishes to find */
  88.         register int s;        /* status return */
  89.     register WINDOW *wp;
  90.  
  91.     if (restflag)        /* don't allow this command if restricted */
  92.         return(resterr());
  93.     if ((s=mlreply("Find file: ", fname, NFILEN)) != TRUE) return(s);
  94.  
  95.     /* look for a window */
  96.     wp = wheadp;
  97.     while (wp != NULL && wp->w_wndp != curwp)
  98.         wp = wp->w_wndp;
  99.     if (wp == NULL) wp = curwp->w_wndp;
  100.     if (wp == NULL) {
  101.         if ((s=splitwind(f, n)) != TRUE) return(s);
  102.         wp = spltwp;
  103.         }
  104.     curwp = wp;
  105.     curbp = wp->w_bufp;
  106.  
  107.     s = getfile(fname, TRUE);
  108.     return(s);
  109. }
  110.  
  111. /*
  112.  * Read the last saved version of a file into the current buffer.
  113.  * Unound.
  114.  */
  115. filerevert(f, n)
  116. {
  117.     char fname[NFILEN];
  118.  
  119.     if (restflag)        /* don't allow this command if restricted */
  120.         return(resterr());
  121.     if ((curbp->b_flag&BFCHG) == 0)         /* Return, no changes.  */
  122.         return (TRUE);
  123.     if (curbp->b_fname[0] == 0) {           /* Must have a name.    */
  124.         mlwrite("No file name");
  125.         return (FALSE);
  126.     }
  127.     strcpy(fname, curbp->b_fname);
  128.     return(readin(fname, TRUE, FALSE));
  129. }
  130. #endif
  131.  
  132. viewfile(f, n)    /* visit a file in VIEW mode */
  133. {
  134.         char fname[NFILEN];    /* file user wishes to find */
  135.         register int s;        /* status return */
  136.  
  137.     if (restflag)        /* don't allow this command if restricted */
  138.         return(resterr());
  139.         if ((s=mlreply("View file: ", fname, NFILEN)) != TRUE)
  140.                 return (s);
  141.     s = getfile(fname, FALSE);
  142.     if (s) {    /* if we succeed, put it in view mode */
  143.         curwp->w_bufp->b_mode |= MDVIEW;
  144.  
  145.         /* scan through and update mode lines of all windows */
  146.         upmode();
  147.     }
  148.     return(s);
  149. }
  150.  
  151. #if    CRYPT
  152. resetkey()    /* reset the encryption key if needed */
  153.  
  154. {
  155.     register int s;    /* return status */
  156.  
  157.     /* turn off the encryption flag */
  158.     cryptflag = FALSE;
  159.  
  160.     /* if we are in crypt mode */
  161.     if (curbp->b_mode & MDCRYPT) {
  162.         if (curbp->b_key[0] == 0) {
  163.             s = setkey(FALSE, 0);
  164.             if (s != TRUE)
  165.                 return(s);
  166.         }
  167.  
  168.         /* let others know... */
  169.         cryptflag = TRUE;
  170.  
  171.         /* and set up the key to be used! */
  172.         /* de-encrypt it */
  173.         crypt((char *)NULL, (unsigned) 0);
  174.         crypt(curbp->b_key, (unsigned) strlen(curbp->b_key));
  175.  
  176.         /* re-encrypt it...seeding it to start */
  177.         crypt((char *)NULL, (unsigned) 0);
  178.         crypt(curbp->b_key, (unsigned) strlen(curbp->b_key));
  179.     }
  180.  
  181.     return(TRUE);
  182. }
  183. #endif
  184.  
  185. getfile(fname, lockfl)
  186.  
  187. char fname[];        /* file name to find */
  188. int lockfl;        /* check the file for locks? */
  189.  
  190. {
  191.         register BUFFER *bp;
  192.         register LINE   *lp;
  193.         register int    i;
  194.         register int    s;
  195.         char bname[NBUFN];    /* buffer name to put file */
  196.  
  197. #if    MSDOS
  198.     mklower(fname);        /* msdos isn't case sensitive */
  199. #endif
  200.         for (bp=bheadp; bp!=NULL; bp=bp->b_bufp) {
  201.                 if ((bp->b_flag&BFINVS)==0 && strcmp(bp->b_fname, fname)==0) {
  202.             swbuffer(bp);
  203.                         lp = curwp->w_dotp;
  204.                         i = curwp->w_ntrows/2;
  205.                         while (i-- && lback(lp)!=curbp->b_linep)
  206.                                 lp = lback(lp);
  207.                         curwp->w_linep = lp;
  208.                         curwp->w_flag |= WFMODE|WFHARD;
  209.                         mlwrite("[Old buffer]");
  210.                         return (TRUE);
  211.                 }
  212.         }
  213.         makename(bname, fname);                 /* New buffer name.     */
  214.         while ((bp=bfind(bname, FALSE, 0)) != NULL) {
  215.         /* old buffer name conflict code */
  216.                 s = mlreply("Buffer name: ", bname, NBUFN);
  217.                 if (s == ABORT)                 /* ^G to just quit      */
  218.                         return (s);
  219.                 if (s == FALSE) {               /* CR to clobber it     */
  220.                         makename(bname, fname);
  221.                         break;
  222.                 }
  223.         }
  224.         if (bp==NULL && (bp=bfind(bname, TRUE, 0))==NULL) {
  225.                 mlwrite("Cannot create buffer");
  226.                 return (FALSE);
  227.         }
  228.         if (--curbp->b_nwnd == 0) {             /* Undisplay.           */
  229.                 curbp->b_dotp = curwp->w_dotp;
  230.                 curbp->b_doto = curwp->w_doto;
  231.                 curbp->b_markp = curwp->w_markp;
  232.                 curbp->b_marko = curwp->w_marko;
  233.                 curbp->b_fcol  = curwp->w_fcol;
  234.         }
  235.         curbp = bp;                             /* Switch to it.        */
  236.         curwp->w_bufp = bp;
  237.         curbp->b_nwnd++;
  238.         return(readin(fname, lockfl, FALSE));   /* Read it in.          */
  239. }
  240.  
  241. /*
  242.     Read file "fname" into the current buffer, blowing away any text
  243.     found there.  Called by both the read and find commands.  Return
  244.     the final status of the read.  Also called by the mainline, to
  245.     read in a file specified on the command line as an argument. 
  246.     The command bound to M-FNR is called after the buffer is set up
  247.     and before it is read. 
  248. */
  249.  
  250. readin(fname, lockfl, recover)
  251.  
  252. char    fname[];    /* name of file to read */
  253. int    lockfl;        /* check for file locks? */
  254. int    recover;    /* recover an autosaved file */
  255.  
  256. {
  257.         register LINE   *lp1;
  258.         register LINE   *lp2;
  259.         register int    i;
  260.         register WINDOW *wp;
  261.         register BUFFER *bp;
  262.         register int    s;
  263.         register int    nbytes;
  264.         register int    nline;
  265.     char mesg[NSTRING];
  266.         char tempname[NFILEN + 4];
  267.  
  268. #if    FILOCK
  269.     if (lockfl && lockchk(fname) == ABORT)
  270.         return(ABORT);
  271. #endif
  272.         bp = curbp;                             /* Cheap.               */
  273.         if ((s=bclear(bp)) != TRUE)             /* Might be old.        */
  274.                 return (s);
  275.         bp->b_flag &= ~(BFINVS|BFCHG);
  276.         strcpy(bp->b_fname, fname);
  277.  
  278.     /* let a user macro get hold of things...if he wants */
  279.     execute(FUNC|'R', HOOK, 1);
  280.  
  281. #if    CRYPT
  282.     s = resetkey();
  283.     if (s != TRUE)
  284.         return(s);
  285. #endif
  286.  
  287.     /* turn off ALL keyboard translation in case we get a dos error */
  288.     TTkclose();
  289.  
  290. #if    ABACKUP
  291.     if (recover) makeasvname(tempname, fname);
  292.     else
  293. #endif
  294.     strcpy(tempname, fname);
  295.  
  296.         if ((s=ffropen(tempname, !recover)) == FIOERR) {  /* Hard file open. */
  297.         strcpy(mesg, "[File error");
  298.                 goto out;
  299.     }
  300.  
  301.         if (s == FIOFNF) {                      /* File not found.      */
  302.                 strcpy(mesg, "[New file");
  303.                 goto out;
  304.         }
  305.  
  306.     /* read the file in */
  307.         mlwrite("[Reading file]");
  308.         nline = 0;
  309.         while ((s=ffgetline()) == FIOSUC) {
  310.                 nbytes = frlen;
  311.                 if ((lp1=lalloc(nbytes)) == NULL) {
  312.                         s = FIOMEM;             /* Keep message on the  */
  313.                         break;                  /* display.             */
  314.                 }
  315.                 lp2 = lback(curbp->b_linep);
  316.                 lp2->l_fp = lp1;
  317.                 lp1->l_fp = curbp->b_linep;
  318.                 lp1->l_bp = lp2;
  319.                 curbp->b_linep->l_bp = lp1;
  320.                 for (i=0; i<nbytes; ++i)
  321.                         lputc(lp1, i, fline[i]);
  322.                 ++nline;
  323.         }
  324.         ffclose();                              /* Ignore errors.       */
  325.     strcpy(mesg, "[");
  326.     if (s==FIOERR) {
  327.         strcat(mesg, "I/O ERROR, ");
  328.         curbp->b_flag |= BFTRUNC;
  329.     }
  330.     if (s == FIOMEM) {
  331.         strcat(mesg, "OUT OF MEMORY, ");
  332.         curbp->b_flag |= BFTRUNC;
  333.     }
  334.     sprintf(&mesg[strlen(mesg)], "Read %d line", nline);
  335.         if (nline > 1)
  336.         strcat(mesg, "s");
  337.  
  338. out:
  339. #if    ABACKUP
  340.     if ((!recover) && (!ffisnewer(fname)))
  341.       strcat(mesg, "; autosave file is newer, consider M-X recover-file");
  342. #endif
  343.     strcat(mesg, "]");
  344.     mlwrite(mesg);
  345.  
  346.     TTkopen();    /* open the keyboard again */
  347.         for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
  348.                 if (wp->w_bufp == curbp) {
  349.                         wp->w_linep = lforw(curbp->b_linep);
  350.                         wp->w_dotp  = lforw(curbp->b_linep);
  351.                         wp->w_doto  = 0;
  352.                         wp->w_markp = NULL;
  353.                         wp->w_marko = 0;
  354.                         wp->w_flag |= WFMODE|WFHARD;
  355.                 }
  356.         }
  357.         if (s == FIOERR || s == FIOFNF)        /* False if error.      */
  358.                 return(FALSE);
  359.         return (TRUE);
  360. }
  361.  
  362. /*
  363.  * Take a file name, and from it
  364.  * fabricate a buffer name. This routine knows
  365.  * about the syntax of file names on the target system.
  366.  * I suppose that this information could be put in
  367.  * a better place than a line of code.
  368.  */
  369. makename(bname, fname)
  370. char    bname[];
  371. char    fname[];
  372. {
  373.         register char *cp1;
  374.         register char *cp2;
  375.  
  376.         cp1 = &fname[0];
  377.         while (*cp1 != 0)
  378.                 ++cp1;
  379.  
  380. #if     AMIGA
  381.         while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='/')
  382.                 --cp1;
  383. #endif
  384. #if     VMS | DECUSC
  385.         while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!=']')
  386.                 --cp1;
  387. #endif
  388. #if     CPM
  389.         while (cp1!=&fname[0] && cp1[-1]!=':')
  390.                 --cp1;
  391. #endif
  392. #if     MSDOS
  393.         while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\'&&cp1[-1]!='/')
  394.                 --cp1;
  395. #endif
  396. #if     ST520
  397.         while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\')
  398.                 --cp1;
  399. #endif
  400. #if     FINDER
  401.         while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\'&&cp1[-1]!='/')
  402.                 --cp1;
  403. #endif
  404. #if     V7 | USG | BSD
  405.         while (cp1!=&fname[0] && cp1[-1]!='/')
  406.                 --cp1;
  407. #endif
  408.         cp2 = &bname[0];
  409.         while (cp2!=&bname[NBUFN-1] && *cp1!=0 && *cp1!=';')
  410.                 *cp2++ = *cp1++;
  411.         *cp2 = 0;
  412. }
  413.  
  414. unqname(name)    /* make sure a buffer name is unique */
  415.  
  416. char *name;    /* name to check on */
  417.  
  418. {
  419.     register char *sp;
  420.  
  421.     /* check to see if it is in the buffer list */
  422.     while (bfind(name, 0, FALSE) != NULL) {
  423.  
  424.         /* go to the end of the name */
  425.         sp = name;
  426.         while (*sp)
  427.             ++sp;
  428.         if (sp == name || (*(sp-1) <'0' || *(sp-1) > '8')) {
  429.             *sp++ = '0';
  430.             *sp = 0;
  431.         } else
  432.             *(--sp) += 1;
  433.     }
  434. }
  435.  
  436. /*
  437.  * Ask for a file name, and write the
  438.  * contents of the current buffer to that file.
  439.  * Update the remembered file name and clear the
  440.  * buffer changed flag. This handling of file names
  441.  * is different from the earlier versions, and
  442.  * is more compatable with Gosling EMACS than
  443.  * with ITS EMACS. Bound to "C-X C-W".
  444.  */
  445. filewrite(f, n)
  446. {
  447.         register int    s;
  448.         char            fname[NFILEN];
  449.  
  450.     if (restflag)        /* don't allow this command if restricted */
  451.         return(resterr());
  452.         if ((s=mlreply("Write file: ", fname, NFILEN)) != TRUE)
  453.                 return (s);
  454.         if ((s=writeout(fname)) == TRUE) {
  455.                 strcpy(curbp->b_fname, fname);
  456.                 curbp->b_flag &= ~BFCHG;
  457.                 upmode();
  458.         }
  459.         return (s);
  460. }
  461.  
  462. /*
  463.  * Save the contents of the current
  464.  * buffer in its associated file. Do nothing
  465.  * if nothing has changed (this may be a bug, not a
  466.  * feature). Error if there is no remembered file
  467.  * name for the buffer. Bound to "C-X C-S". May
  468.  * get called by "C-Z".
  469.  */
  470. filesave(f, n)
  471. {
  472.         register int    s;
  473.  
  474.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  475.         return(rdonly());    /* we are in read only mode    */
  476.         if ((curbp->b_flag&BFCHG) == 0)         /* Return, no changes.  */
  477.                 return (TRUE);
  478.         if (curbp->b_fname[0] == 0) {           /* Must have a name.    */
  479.                 mlwrite("No file name");
  480.                 return (FALSE);
  481.         }
  482.         /* complain about truncated files */
  483.         if (curbp->b_flag & BFTRUNC) {
  484.             if (mlyesno("Truncated file..write it out") == FALSE) {
  485.                 mlwrite("[Aborted]");
  486.                 return(FALSE);
  487.             }
  488.         }
  489.         /* complain about narrowed buffers */
  490.         if (curbp->b_flag & BFNAROW) {
  491.             if (mlyesno("Narrows buffer..write it out") == FALSE) {
  492.                 mlwrite("[Aborted]");
  493.                 return(FALSE);
  494.             }
  495.         }
  496.         if ((s=writeout(curbp->b_fname)) == TRUE) {
  497.                 curbp->b_flag &= ~BFCHG;
  498.                 upmode();
  499.         }
  500.         return (s);
  501. }
  502.  
  503. /*
  504.  * This function performs the details of file
  505.  * writing. Uses the file management routines in the
  506.  * "fileio.c" package. The number of lines written is
  507.  * displayed. Sadly, it looks inside a LINE; provide
  508.  * a macro for this. Most of the grief is error
  509.  * checking of some sort.
  510.  */
  511. writeout(fn)
  512. char    *fn;
  513. {
  514.         register int    s;
  515.         register LINE   *lp;
  516.         register int    nline;
  517.  
  518. #if    CRYPT
  519.     s = resetkey();
  520.     if (s != TRUE)
  521.         return(s);
  522. #endif
  523.     /* turn off ALL keyboard translation in case we get a dos error */
  524.     TTkclose();
  525.  
  526.         if ((s=ffwopen(fn)) != FIOSUC) {        /* Open writes message. */
  527.         TTkopen();
  528.                 return (FALSE);
  529.         }
  530.     mlwrite("[Writing...]");        /* tell us were writing */
  531.         lp = lforw(curbp->b_linep);             /* First line.          */
  532.         nline = 0;                              /* Number of lines.     */
  533.         while (lp != curbp->b_linep) {
  534.                 if ((s=ffputline(&lp->l_text[0], llength(lp))) != FIOSUC)
  535.                         break;
  536.                 ++nline;
  537.                 lp = lforw(lp);
  538.         }
  539.         if (s == FIOSUC) {                      /* No write error.      */
  540.                 s = ffclose();
  541.                 if (s == FIOSUC) {              /* No close error.      */
  542.                         if (nline == 1)
  543.                                 mlwrite("[Wrote 1 line]");
  544.                         else
  545.                                 mlwrite("[Wrote %d lines]", nline);
  546.                 }
  547.         } else                                  /* Ignore close error   */
  548.                 ffclose();                      /* if a write error.    */
  549.     TTkopen();
  550.         if (s != FIOSUC)                        /* Some sort of error.  */
  551.                 return (FALSE);
  552.         return (TRUE);
  553. }
  554.  
  555. /*
  556.  * The command allows the user
  557.  * to modify the file name associated with
  558.  * the current buffer. It is like the "f" command
  559.  * in UNIX "ed". The operation is simple; just zap
  560.  * the name in the BUFFER structure, and mark the windows
  561.  * as needing an update. You can type a blank line at the
  562.  * prompt if you wish.
  563.  */
  564. filename(f, n)
  565. {
  566.         register int    s;
  567.         char            fname[NFILEN];
  568.  
  569.     if (restflag)        /* don't allow this command if restricted */
  570.         return(resterr());
  571.         if ((s=mlreply("Name: ", fname, NFILEN)) == ABORT)
  572.                 return (s);
  573.         if (s == FALSE)
  574.                 strcpy(curbp->b_fname, "");
  575.         else
  576.                 strcpy(curbp->b_fname, fname);
  577.         upmode();
  578.     curbp->b_mode &= ~MDVIEW;    /* no longer read only mode */
  579.         return (TRUE);
  580. }
  581.  
  582. /*
  583.  * Insert file "fname" into the current
  584.  * buffer, Called by insert file command. Return the final
  585.  * status of the read.
  586.  */
  587. ifile(fname)
  588. char    fname[];
  589. {
  590.         register LINE   *lp0;
  591.         register LINE   *lp1;
  592.         register LINE   *lp2;
  593.         register int    i;
  594.         register BUFFER *bp;
  595.         register int    s;
  596.         register int    nbytes;
  597.         register int    nline;
  598.     char mesg[NSTRING];
  599.  
  600.         bp = curbp;                             /* Cheap.               */
  601.         bp->b_flag |= BFCHG;            /* we have changed    */
  602.     bp->b_flag &= ~BFINVS;            /* and are not temporary*/
  603.         if ((s=ffropen(fname,FALSE)) == FIOERR) /* Hard file open.      */
  604.                 goto out;
  605.         if (s == FIOFNF) {                      /* File not found.      */
  606.                 mlwrite("[No such file]");
  607.         return(FALSE);
  608.         }
  609.         mlwrite("[Inserting file]");
  610.  
  611. #if    CRYPT
  612.     s = resetkey();
  613.     if (s != TRUE)
  614.         return(s);
  615. #endif
  616.     /* back up a line and save the mark here */
  617.     curwp->w_dotp = lback(curwp->w_dotp);
  618.     curwp->w_doto = 0;
  619.     curwp->w_markp = curwp->w_dotp;
  620.     curwp->w_marko = 0;
  621.  
  622.         nline = 0;
  623.         while ((s=ffgetline()) == FIOSUC) {
  624.                 nbytes = frlen;
  625.                 if ((lp1=lalloc(nbytes)) == NULL) {
  626.                         s = FIOMEM;             /* Keep message on the  */
  627.                         break;                  /* display.             */
  628.                 }
  629.         lp0 = curwp->w_dotp;    /* line previous to insert */
  630.         lp2 = lp0->l_fp;    /* line after insert */
  631.  
  632.         /* re-link new line between lp0 and lp2 */
  633.         lp2->l_bp = lp1;
  634.         lp0->l_fp = lp1;
  635.         lp1->l_bp = lp0;
  636.         lp1->l_fp = lp2;
  637.  
  638.         /* and advance and write out the current line */
  639.         curwp->w_dotp = lp1;
  640.                 for (i=0; i<nbytes; ++i)
  641.                         lputc(lp1, i, fline[i]);
  642.                 ++nline;
  643.         }
  644.         ffclose();                              /* Ignore errors.       */
  645.     curwp->w_markp = lforw(curwp->w_markp);
  646.     strcpy(mesg, "[");
  647.     if (s==FIOERR) {
  648.         strcat(mesg, "I/O ERROR, ");
  649.         curbp->b_flag |= BFTRUNC;
  650.     }
  651.     if (s == FIOMEM) {
  652.         strcat(mesg, "OUT OF MEMORY, ");
  653.         curbp->b_flag |= BFTRUNC;
  654.     }
  655.     sprintf(&mesg[strlen(mesg)], "Inserted %d line", nline);
  656.         if (nline > 1)
  657.         strcat(mesg, "s");
  658.     strcat(mesg, "]");
  659.     mlwrite(mesg);
  660.  
  661. out:
  662.     /* advance to the next line and mark the window for changes */
  663.     curwp->w_dotp = lforw(curwp->w_dotp);
  664.     curwp->w_flag |= WFHARD | WFMODE;
  665.  
  666.     /* copy window parameters back to the buffer structure */
  667.     curbp->b_dotp = curwp->w_dotp;
  668.     curbp->b_doto = curwp->w_doto;
  669.     curbp->b_markp = curwp->w_markp;
  670.     curbp->b_marko = curwp->w_marko;
  671.     curbp->b_fcol  = curwp->w_fcol;
  672.  
  673.         if (s == FIOERR)                        /* False if error.      */
  674.                 return (FALSE);
  675.         return (TRUE);
  676. }
  677.  
  678. #if    ACMODE
  679. /* set CMODE based on buffer name */
  680. acmode(f, n)
  681. {
  682.     char *s;
  683.     int len;
  684.  
  685.     s = curbp->b_fname;
  686.     if (s && strlen(s) > 1) {
  687.         len = strlen(s) - 1;
  688.         while (len >= 0 && s[len] != '.') len--;
  689.         if (len >= 0 && s[len] == '.') {
  690.             len++;
  691.             if (s[len] == 'c' || s[len] == 'h' ||
  692.                 s[len] == 'p' || s[len] == 'f' ||
  693.                 s[len] == 'a')
  694.                 curbp->b_mode |= MDCMOD;
  695.         }
  696.     }
  697.     return(TRUE);
  698. }
  699. #endif
  700.  
  701. #if    ABACKUP
  702.  
  703. /* make an autosave name */
  704.  
  705. makeasvname(tempname, fname)
  706. char *tempname, *fname;
  707. {
  708.     char *i, *j;
  709.     char c;
  710.  
  711.     j = tempname;
  712.     for(i=tempname; (c = *i = *fname++) != '\0'; i++)
  713.         if (c == '.') j = i;
  714.         else if (c == '/' || c == '\\' || c == ':' || c == ']')
  715.             j = tempname;
  716.     if (j == tempname) j = i;
  717.     strcpy(j, ".asv");
  718. }
  719.  
  720. /*
  721.  * Recover an auto-saved version of the file in the current buffer.
  722.  */
  723. filercover(f, n)
  724. {
  725.         register int    s;
  726.         char fname[NFILEN];
  727.  
  728.     if (restflag)        /* don't allow this command if restricted */
  729.         return(resterr());
  730.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  731.         return(rdonly());    /* we are in read only mode    */
  732.         if (curbp->b_fname[0] == 0) {           /* Must have a name.    */
  733.                 mlwrite("[No file name]");
  734.                 return (FALSE);
  735.         }
  736.     strcpy(fname, curbp->b_fname);
  737.     s = readin(fname, TRUE, TRUE);
  738.     curbp->b_flag |= BFCHG;
  739.     return(s);
  740. }
  741.  
  742. /*
  743.  * Backup the contents of the current
  744.  * buffer in its associated file. Do nothing
  745.  * if nothing has changed (this may be a bug, not a
  746.  * feature). Error if there is no remembered file
  747.  * name for the buffer.  Called when an auto-save is done.
  748.  */
  749. fileback(f, n)
  750. {
  751.     char tempname[NFILEN + 4];
  752.  
  753.     if (restflag)        /* don't allow this command if restricted */
  754.         return(resterr());
  755.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  756.         return(rdonly());    /* we are in read only mode    */
  757.         if ((curbp->b_flag&BFCHG) == 0)         /* Return, no changes.  */
  758.                 return (TRUE);
  759.         if (curbp->b_fname[0] == 0) {           /* Must have a name.    */
  760.                 mlwrite("[No file name for auto-save]");
  761.                 return (FALSE);
  762.         }
  763.     makeasvname(tempname, curbp->b_fname);
  764.     return(writeout(tempname));
  765. }
  766.  
  767. #endif
  768.  
  769.