/* vi:set ts=8 sts=4 sw=4 noet:
 *
 * VIM - Vi IMproved	by Bram Moolenaar
 *
 * Do ":help uganda"  in Vim to read copying and usage conditions.
 * Do ":help credits" in Vim to see a list of people who contributed.
 * See README.txt for an overview of the Vim source code.
 */

// for debugging
// #define CHECK(c, s)	do { if (c) emsg((s)); } while (0)
#define CHECK(c, s)	do { /**/ } while (0)

/*
 * memline.c: Contains the functions for appending, deleting and changing the
 * text lines. The memfile functions are used to store the information in
 * blocks of memory, backed up by a file. The structure of the information is
 * a tree.  The root of the tree is a pointer block. The leaves of the tree
 * are data blocks. In between may be several layers of pointer blocks,
 * forming branches.
 *
 * Three types of blocks are used:
 * - Block nr 0 contains information for recovery
 * - Pointer blocks contain list of pointers to other blocks.
 * - Data blocks contain the actual text.
 *
 * Block nr 0 contains the block0 structure (see below).
 *
 * Block nr 1 is the first pointer block. It is the root of the tree.
 * Other pointer blocks are branches.
 *
 *  If a line is too big to fit in a single page, the block containing that
 *  line is made big enough to hold the line. It may span several pages.
 *  Otherwise all blocks are one page.
 *
 *  A data block that was filled when starting to edit a file and was not
 *  changed since then, can have a negative block number. This means that it
 *  has not yet been assigned a place in the file. When recovering, the lines
 *  in this data block can be read from the original file. When the block is
 *  changed (lines appended/deleted/changed) or when it is flushed it gets a
 *  positive number. Use mf_trans_del() to get the new number, before calling
 *  mf_get().
 */

#include "vim.h"

#ifndef UNIX		// it's in os_unix.h for Unix
# include <time.h>
#endif

#if defined(SASC) || defined(__amigaos4__)
# include <proto/dos.h>	    // for Open() and Close()
#endif

typedef struct block0		ZERO_BL;    // contents of the first block
typedef struct pointer_block	PTR_BL;	    // contents of a pointer block
typedef struct data_block	DATA_BL;    // contents of a data block
typedef struct pointer_entry	PTR_EN;	    // block/line-count pair

#define DATA_ID	       (('d' << 8) + 'a')   // data block id
#define PTR_ID	       (('p' << 8) + 't')   // pointer block id
#define BLOCK0_ID0     'b'		    // block 0 id 0
#define BLOCK0_ID1     '0'		    // block 0 id 1
#define BLOCK0_ID1_C0  'c'		    // block 0 id 1 'cm' 0
#define BLOCK0_ID1_C1  'C'		    // block 0 id 1 'cm' 1
#define BLOCK0_ID1_C2  'd'		    // block 0 id 1 'cm' 2

#if defined(FEAT_CRYPT)
static int id1_codes[] = {
    BLOCK0_ID1_C0,  // CRYPT_M_ZIP
    BLOCK0_ID1_C1,  // CRYPT_M_BF
    BLOCK0_ID1_C2,  // CRYPT_M_BF2
};
#endif

/*
 * pointer to a block, used in a pointer block
 */
struct pointer_entry
{
    blocknr_T	pe_bnum;	// block number
    linenr_T	pe_line_count;	// number of lines in this branch
    linenr_T	pe_old_lnum;	// lnum for this block (for recovery)
    int		pe_page_count;	// number of pages in block pe_bnum
};

/*
 * A pointer block contains a list of branches in the tree.
 */
struct pointer_block
{
    short_u	pb_id;		// ID for pointer block: PTR_ID
    short_u	pb_count;	// number of pointers in this block
    short_u	pb_count_max;	// maximum value for pb_count
    PTR_EN	pb_pointer[1];	// list of pointers to blocks (actually longer)
				// followed by empty space until end of page
};

/*
 * A data block is a leaf in the tree.
 *
 * The text of the lines is at the end of the block. The text of the first line
 * in the block is put at the end, the text of the second line in front of it,
 * etc. Thus the order of the lines is the opposite of the line number.
 */
struct data_block
{
    short_u	db_id;		// ID for data block: DATA_ID
    unsigned	db_free;	// free space available
    unsigned	db_txt_start;	// byte where text starts
    unsigned	db_txt_end;	// byte just after data block
    linenr_T	db_line_count;	// number of lines in this block
    unsigned	db_index[1];	// index for start of line (actually bigger)
				// followed by empty space up to db_txt_start
				// followed by the text in the lines until
				// end of page
};

/*
 * The low bits of db_index hold the actual index. The topmost bit is
 * used for the global command to be able to mark a line.
 * This method is not clean, but otherwise there would be at least one extra
 * byte used for each line.
 * The mark has to be in this place to keep it with the correct line when other
 * lines are inserted or deleted.
 */
#define DB_MARKED	((unsigned)1 << ((sizeof(unsigned) * 8) - 1))
#define DB_INDEX_MASK	(~DB_MARKED)

#define INDEX_SIZE  (sizeof(unsigned))	    // size of one db_index entry
#define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE)  // size of data block header

#define B0_FNAME_SIZE_ORG	900	// what it was in older versions
#define B0_FNAME_SIZE_NOCRYPT	898	// 2 bytes used for other things
#define B0_FNAME_SIZE_CRYPT	890	// 10 bytes used for other things
#define B0_UNAME_SIZE		40
#define B0_HNAME_SIZE		40
/*
 * Restrict the numbers to 32 bits, otherwise most compilers will complain.
 * This won't detect a 64 bit machine that only swaps a byte in the top 32
 * bits, but that is crazy anyway.
 */
#define B0_MAGIC_LONG	0x30313233L
#define B0_MAGIC_INT	0x20212223L
#define B0_MAGIC_SHORT	0x10111213L
#define B0_MAGIC_CHAR	0x55

/*
 * Block zero holds all info about the swap file.
 *
 * NOTE: DEFINITION OF BLOCK 0 SHOULD NOT CHANGE! It would make all existing
 * swap files unusable!
 *
 * If size of block0 changes anyway, adjust MIN_SWAP_PAGE_SIZE in vim.h!!
 *
 * This block is built up of single bytes, to make it portable across
 * different machines. b0_magic_* is used to check the byte order and size of
 * variables, because the rest of the swap file is not portable.
 */
struct block0
{
    char_u	b0_id[2];	// id for block 0: BLOCK0_ID0 and BLOCK0_ID1,
				// BLOCK0_ID1_C0, BLOCK0_ID1_C1, etc.
    char_u	b0_version[10];	// Vim version string
    char_u	b0_page_size[4];// number of bytes per page
    char_u	b0_mtime[4];	// last modification time of file
    char_u	b0_ino[4];	// inode of b0_fname
    char_u	b0_pid[4];	// process id of creator (or 0)
    char_u	b0_uname[B0_UNAME_SIZE]; // name of user (uid if no name)
    char_u	b0_hname[B0_HNAME_SIZE]; // host name (if it has a name)
    char_u	b0_fname[B0_FNAME_SIZE_ORG]; // name of file being edited
    long	b0_magic_long;	// check for byte order of long
    int		b0_magic_int;	// check for byte order of int
    short	b0_magic_short;	// check for byte order of short
    char_u	b0_magic_char;	// check for last char
};

/*
 * Note: b0_dirty and b0_flags are put at the end of the file name.  For very
 * long file names in older versions of Vim they are invalid.
 * The 'fileencoding' comes before b0_flags, with a NUL in front.  But only
 * when there is room, for very long file names it's omitted.
 */
#define B0_DIRTY	0x55
#define b0_dirty	b0_fname[B0_FNAME_SIZE_ORG - 1]

/*
 * The b0_flags field is new in Vim 7.0.
 */
#define b0_flags	b0_fname[B0_FNAME_SIZE_ORG - 2]

/*
 * Crypt seed goes here, 8 bytes.  New in Vim 7.3.
 * Without encryption these bytes may be used for 'fenc'.
 */
#define b0_seed		b0_fname[B0_FNAME_SIZE_ORG - 2 - MF_SEED_LEN]

// The lowest two bits contain the fileformat.  Zero means it's not set
// (compatible with Vim 6.x), otherwise it's EOL_UNIX + 1, EOL_DOS + 1 or
// EOL_MAC + 1.
#define B0_FF_MASK	3

// Swap file is in directory of edited file.  Used to find the file from
// different mount points.
#define B0_SAME_DIR	4

// The 'fileencoding' is at the end of b0_fname[], with a NUL in front of it.
// When empty there is only the NUL.
#define B0_HAS_FENC	8

#define STACK_INCR	5	// nr of entries added to ml_stack at a time

/*
 * The line number where the first mark may be is remembered.
 * If it is 0 there are no marks at all.
 * (always used for the current buffer only, no buffer change possible while
 * executing a global command).
 */
static linenr_T	lowest_marked = 0;

/*
 * arguments for ml_find_line()
 */
#define ML_DELETE	0x11	    // delete line
#define ML_INSERT	0x12	    // insert line
#define ML_FIND		0x13	    // just find the line
#define ML_FLUSH	0x02	    // flush locked block
#define ML_SIMPLE(x)	(x & 0x10)  // DEL, INS or FIND

// argument for ml_upd_block0()
typedef enum {
      UB_FNAME = 0	// update timestamp and filename
    , UB_SAME_DIR       // update the B0_SAME_DIR flag
    , UB_CRYPT		// update crypt key
} upd_block0_T;

#ifdef FEAT_CRYPT
static void ml_set_b0_crypt(buf_T *buf, ZERO_BL *b0p);
#endif
static void ml_upd_block0(buf_T *buf, upd_block0_T what);
static void set_b0_fname(ZERO_BL *, buf_T *buf);
static void set_b0_dir_flag(ZERO_BL *b0p, buf_T *buf);
static void add_b0_fenc(ZERO_BL *b0p, buf_T *buf);
static time_t swapfile_info(char_u *);
static int recov_file_names(char_u **, char_u *, int prepend_dot);
static int ml_delete_int(buf_T *, linenr_T, int);
static char_u *findswapname(buf_T *, char_u **, char_u *);
static void ml_flush_line(buf_T *);
static bhdr_T *ml_new_data(memfile_T *, int, int);
static bhdr_T *ml_new_ptr(memfile_T *);
static bhdr_T *ml_find_line(buf_T *, linenr_T, int);
static int ml_add_stack(buf_T *);
static void ml_lineadd(buf_T *, int);
static int b0_magic_wrong(ZERO_BL *);
#ifdef CHECK_INODE
static int fnamecmp_ino(char_u *, char_u *, long);
#endif
static void long_to_char(long, char_u *);
static long char_to_long(char_u *);
#ifdef FEAT_CRYPT
static cryptstate_T *ml_crypt_prepare(memfile_T *mfp, off_T offset, int reading);
#endif
#ifdef FEAT_BYTEOFF
static void ml_updatechunk(buf_T *buf, long line, long len, int updtype);
#endif

/*
 * Open a new memline for "buf".
 *
 * Return FAIL for failure, OK otherwise.
 */
    int
ml_open(buf_T *buf)
{
    memfile_T	*mfp;
    bhdr_T	*hp = NULL;
    ZERO_BL	*b0p;
    PTR_BL	*pp;
    DATA_BL	*dp;

    /*
     * init fields in memline struct
     */
    buf->b_ml.ml_stack_size = 0; // no stack yet
    buf->b_ml.ml_stack = NULL;	// no stack yet
    buf->b_ml.ml_stack_top = 0;	// nothing in the stack
    buf->b_ml.ml_locked = NULL;	// no cached block
    buf->b_ml.ml_line_lnum = 0;	// no cached line
#ifdef FEAT_BYTEOFF
    buf->b_ml.ml_chunksize = NULL;
#endif

    if (cmdmod.noswapfile)
	buf->b_p_swf = FALSE;

    /*
     * When 'updatecount' is non-zero swap file may be opened later.
     */
    if (p_uc && buf->b_p_swf)
	buf->b_may_swap = TRUE;
    else
	buf->b_may_swap = FALSE;

    /*
     * Open the memfile.  No swap file is created yet.
     */
    mfp = mf_open(NULL, 0);
    if (mfp == NULL)
	goto error;

    buf->b_ml.ml_mfp = mfp;
#ifdef FEAT_CRYPT
    mfp->mf_buffer = buf;
#endif
    buf->b_ml.ml_flags = ML_EMPTY;
    buf->b_ml.ml_line_count = 1;
#ifdef FEAT_LINEBREAK
    curwin->w_nrwidth_line_count = 0;
#endif

/*
 * fill block0 struct and write page 0
 */
    if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
	goto error;
    if (hp->bh_bnum != 0)
    {
	iemsg(_("E298: Didn't get block nr 0?"));
	goto error;
    }
    b0p = (ZERO_BL *)(hp->bh_data);

    b0p->b0_id[0] = BLOCK0_ID0;
    b0p->b0_id[1] = BLOCK0_ID1;
    b0p->b0_magic_long = (long)B0_MAGIC_LONG;
    b0p->b0_magic_int = (int)B0_MAGIC_INT;
    b0p->b0_magic_short = (short)B0_MAGIC_SHORT;
    b0p->b0_magic_char = B0_MAGIC_CHAR;
    mch_memmove(b0p->b0_version, "VIM ", 4);
    STRNCPY(b0p->b0_version + 4, Version, 6);
    long_to_char((long)mfp->mf_page_size, b0p->b0_page_size);

#ifdef FEAT_SPELL
    if (!buf->b_spell)
#endif
    {
	b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
	b0p->b0_flags = get_fileformat(buf) + 1;
	set_b0_fname(b0p, buf);
	(void)get_user_name(b0p->b0_uname, B0_UNAME_SIZE);
	b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL;
	mch_get_host_name(b0p->b0_hname, B0_HNAME_SIZE);
	b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL;
	long_to_char(mch_get_pid(), b0p->b0_pid);
#ifdef FEAT_CRYPT
	ml_set_b0_crypt(buf, b0p);
#endif
    }

    /*
     * Always sync block number 0 to disk, so we can check the file name in
     * the swap file in findswapname(). Don't do this for a help files or
     * a spell buffer though.
     * Only works when there's a swapfile, otherwise it's done when the file
     * is created.
     */
    mf_put(mfp, hp, TRUE, FALSE);
    if (!buf->b_help && !B_SPELL(buf))
	(void)mf_sync(mfp, 0);

    /*
     * Fill in root pointer block and write page 1.
     */
    if ((hp = ml_new_ptr(mfp)) == NULL)
	goto error;
    if (hp->bh_bnum != 1)
    {
	iemsg(_("E298: Didn't get block nr 1?"));
	goto error;
    }
    pp = (PTR_BL *)(hp->bh_data);
    pp->pb_count = 1;
    pp->pb_pointer[0].pe_bnum = 2;
    pp->pb_pointer[0].pe_page_count = 1;
    pp->pb_pointer[0].pe_old_lnum = 1;
    pp->pb_pointer[0].pe_line_count = 1;    // line count after insertion
    mf_put(mfp, hp, TRUE, FALSE);

    /*
     * Allocate first data block and create an empty line 1.
     */
    if ((hp = ml_new_data(mfp, FALSE, 1)) == NULL)
	goto error;
    if (hp->bh_bnum != 2)
    {
	iemsg(_("E298: Didn't get block nr 2?"));
	goto error;
    }

    dp = (DATA_BL *)(hp->bh_data);
    dp->db_index[0] = --dp->db_txt_start;	// at end of block
    dp->db_free -= 1 + INDEX_SIZE;
    dp->db_line_count = 1;
    *((char_u *)dp + dp->db_txt_start) = NUL;	// empty line

    return OK;

error:
    if (mfp != NULL)
    {
	if (hp)
	    mf_put(mfp, hp, FALSE, FALSE);
	mf_close(mfp, TRUE);	    // will also free(mfp->mf_fname)
    }
    buf->b_ml.ml_mfp = NULL;
    return FAIL;
}

#if defined(FEAT_CRYPT) || defined(PROTO)
/*
 * Prepare encryption for "buf" for the current key and method.
 */
    static void
ml_set_mfp_crypt(buf_T *buf)
{
    if (*buf->b_p_key != NUL)
    {
	int method_nr = crypt_get_method_nr(buf);

	if (method_nr > CRYPT_M_ZIP)
	{
	    // Generate a seed and store it in the memfile.
	    sha2_seed(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN, NULL, 0);
	}
    }
}

/*
 * Prepare encryption for "buf" with block 0 "b0p".
 */
    static void
ml_set_b0_crypt(buf_T *buf, ZERO_BL *b0p)
{
    if (*buf->b_p_key == NUL)
	b0p->b0_id[1] = BLOCK0_ID1;
    else
    {
	int method_nr = crypt_get_method_nr(buf);

	b0p->b0_id[1] = id1_codes[method_nr];
	if (method_nr > CRYPT_M_ZIP)
	{
	    // Generate a seed and store it in block 0 and in the memfile.
	    sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0);
	    mch_memmove(buf->b_ml.ml_mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
	}
    }
}

/*
 * Called after the crypt key or 'cryptmethod' was changed for "buf".
 * Will apply this to the swapfile.
 * "old_key" is the previous key.  It is equal to buf->b_p_key when
 * 'cryptmethod' is changed.
 * "old_cm" is the previous 'cryptmethod'.  It is equal to the current
 * 'cryptmethod' when 'key' is changed.
 */
    void
ml_set_crypt_key(
    buf_T	*buf,
    char_u	*old_key,
    char_u	*old_cm)
{
    memfile_T	*mfp = buf->b_ml.ml_mfp;
    bhdr_T	*hp;
    int		page_count;
    int		idx;
    long	error;
    infoptr_T	*ip;
    PTR_BL	*pp;
    DATA_BL	*dp;
    blocknr_T	bnum;
    int		top;
    int		old_method;

    if (mfp == NULL)
	return;  // no memfile yet, nothing to do
    old_method = crypt_method_nr_from_name(old_cm);

    // First make sure the swapfile is in a consistent state, using the old
    // key and method.
    {
	char_u *new_key = buf->b_p_key;
	char_u *new_buf_cm = buf->b_p_cm;

	buf->b_p_key = old_key;
	buf->b_p_cm = old_cm;
	ml_preserve(buf, FALSE);
	buf->b_p_key = new_key;
	buf->b_p_cm = new_buf_cm;
    }

    // Set the key, method and seed to be used for reading, these must be the
    // old values.
    mfp->mf_old_key = old_key;
    mfp->mf_old_cm = old_method;
    if (old_method > 0 && *old_key != NUL)
	mch_memmove(mfp->mf_old_seed, mfp->mf_seed, MF_SEED_LEN);

    // Update block 0 with the crypt flag and may set a new seed.
    ml_upd_block0(buf, UB_CRYPT);

    if (mfp->mf_infile_count > 2)
    {
	/*
	 * Need to read back all data blocks from disk, decrypt them with the
	 * old key/method and mark them to be written. The algorithm is
	 * similar to what happens in ml_recover(), but we skip negative block
	 * numbers.
	 */
	ml_flush_line(buf);		    // flush buffered line
	(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); // flush locked block

	hp = NULL;
	bnum = 1;		// start with block 1
	page_count = 1;		// which is 1 page
	idx = 0;		// start with first index in block 1
	error = 0;
	buf->b_ml.ml_stack_top = 0;
	VIM_CLEAR(buf->b_ml.ml_stack);
	buf->b_ml.ml_stack_size = 0;	// no stack yet

	for ( ; !got_int; line_breakcheck())
	{
	    if (hp != NULL)
		mf_put(mfp, hp, FALSE, FALSE);	// release previous block

	    // get the block (pointer or data)
	    if ((hp = mf_get(mfp, (blocknr_T)bnum, page_count)) == NULL)
	    {
		if (bnum == 1)
		    break;
		++error;
	    }
	    else
	    {
		pp = (PTR_BL *)(hp->bh_data);
		if (pp->pb_id == PTR_ID)	// it is a pointer block
		{
		    if (pp->pb_count == 0)
		    {
			// empty block?
			++error;
		    }
		    else if (idx < (int)pp->pb_count)	// go a block deeper
		    {
			if (pp->pb_pointer[idx].pe_bnum < 0)
			{
			    // Skip data block with negative block number.
			    // Should not happen, because of the ml_preserve()
			    // above. Get same block again for next index.
			    ++idx;
			    continue;
			}

			// going one block deeper in the tree, new entry in
			// stack
			if ((top = ml_add_stack(buf)) < 0)
			{
			    ++error;
			    break;		    // out of memory
			}
			ip = &(buf->b_ml.ml_stack[top]);
			ip->ip_bnum = bnum;
			ip->ip_index = idx;

			bnum = pp->pb_pointer[idx].pe_bnum;
			page_count = pp->pb_pointer[idx].pe_page_count;
			idx = 0;
			continue;
		    }
		}
		else	    // not a pointer block
		{
		    dp = (DATA_BL *)(hp->bh_data);
		    if (dp->db_id != DATA_ID)	// block id wrong
			++error;
		    else
		    {
			// It is a data block, need to write it back to disk.
			mf_put(mfp, hp, TRUE, FALSE);
			hp = NULL;
		    }
		}
	    }

	    if (buf->b_ml.ml_stack_top == 0)	// finished
		break;

	    // go one block up in the tree
	    ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]);
	    bnum = ip->ip_bnum;
	    idx = ip->ip_index + 1;	    // go to next index
	    page_count = 1;
	}
	if (hp != NULL)
	    mf_put(mfp, hp, FALSE, FALSE);  // release previous block

	if (error > 0)
	    emsg(_("E843: Error while updating swap file crypt"));
    }

    mfp->mf_old_key = NULL;
}
#endif

/*
 * ml_setname() is called when the file name of "buf" has been changed.
 * It may rename the swap file.
 */
    void
ml_setname(buf_T *buf)
{
    int		success = FALSE;
    memfile_T	*mfp;
    char_u	*fname;
    char_u	*dirp;
#if defined(MSWIN)
    char_u	*p;
#endif

    mfp = buf->b_ml.ml_mfp;
    if (mfp->mf_fd < 0)		    // there is no swap file yet
    {
	/*
	 * When 'updatecount' is 0 and 'noswapfile' there is no swap file.
	 * For help files we will make a swap file now.
	 */
	if (p_uc != 0 && !cmdmod.noswapfile)
	    ml_open_file(buf);	    // create a swap file
	return;
    }

    /*
     * Try all directories in the 'directory' option.
     */
    dirp = p_dir;
    for (;;)
    {
	if (*dirp == NUL)	    // tried all directories, fail
	    break;
	fname = findswapname(buf, &dirp, mfp->mf_fname);
						    // alloc's fname
	if (dirp == NULL)	    // out of memory
	    break;
	if (fname == NULL)	    // no file name found for this dir
	    continue;

#if defined(MSWIN)
	/*
	 * Set full pathname for swap file now, because a ":!cd dir" may
	 * change directory without us knowing it.
	 */
	p = FullName_save(fname, FALSE);
	vim_free(fname);
	fname = p;
	if (fname == NULL)
	    continue;
#endif
	// if the file name is the same we don't have to do anything
	if (fnamecmp(fname, mfp->mf_fname) == 0)
	{
	    vim_free(fname);
	    success = TRUE;
	    break;
	}
	// need to close the swap file before renaming
	if (mfp->mf_fd >= 0)
	{
	    close(mfp->mf_fd);
	    mfp->mf_fd = -1;
	}

	// try to rename the swap file
	if (vim_rename(mfp->mf_fname, fname) == 0)
	{
	    success = TRUE;
	    vim_free(mfp->mf_fname);
	    mfp->mf_fname = fname;
	    vim_free(mfp->mf_ffname);
#if defined(MSWIN)
	    mfp->mf_ffname = NULL;  // mf_fname is full pathname already
#else
	    mf_set_ffname(mfp);
#endif
	    ml_upd_block0(buf, UB_SAME_DIR);
	    break;
	}
	vim_free(fname);	    // this fname didn't work, try another
    }

    if (mfp->mf_fd == -1)	    // need to (re)open the swap file
    {
	mfp->mf_fd = mch_open((char *)mfp->mf_fname, O_RDWR | O_EXTRA, 0);
	if (mfp->mf_fd < 0)
	{
	    // could not (re)open the swap file, what can we do????
	    emsg(_("E301: Oops, lost the swap file!!!"));
	    return;
	}
#ifdef HAVE_FD_CLOEXEC
	{
	    int fdflags = fcntl(mfp->mf_fd, F_GETFD);
	    if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0)
		(void)fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC);
	}
#endif
    }
    if (!success)
	emsg(_("E302: Could not rename swap file"));
}

/*
 * Open a file for the memfile for all buffers that are not readonly or have
 * been modified.
 * Used when 'updatecount' changes from zero to non-zero.
 */
    void
ml_open_files(void)
{
    buf_T	*buf;

    FOR_ALL_BUFFERS(buf)
	if (!buf->b_p_ro || buf->b_changed)
	    ml_open_file(buf);
}

/*
 * Open a swap file for an existing memfile, if there is no swap file yet.
 * If we are unable to find a file name, mf_fname will be NULL
 * and the memfile will be in memory only (no recovery possible).
 */
    void
ml_open_file(buf_T *buf)
{
    memfile_T	*mfp;
    char_u	*fname;
    char_u	*dirp;

    mfp = buf->b_ml.ml_mfp;
    if (mfp == NULL || mfp->mf_fd >= 0 || !buf->b_p_swf || cmdmod.noswapfile)
	return;		// nothing to do

#ifdef FEAT_SPELL
    // For a spell buffer use a temp file name.
    if (buf->b_spell)
    {
	fname = vim_tempname('s', FALSE);
	if (fname != NULL)
	    (void)mf_open_file(mfp, fname);	// consumes fname!
	buf->b_may_swap = FALSE;
	return;
    }
#endif

    /*
     * Try all directories in 'directory' option.
     */
    dirp = p_dir;
    for (;;)
    {
	if (*dirp == NUL)
	    break;
	// There is a small chance that between choosing the swap file name
	// and creating it, another Vim creates the file.  In that case the
	// creation will fail and we will use another directory.
	fname = findswapname(buf, &dirp, NULL); // allocates fname
	if (dirp == NULL)
	    break;  // out of memory
	if (fname == NULL)
	    continue;
	if (mf_open_file(mfp, fname) == OK)	// consumes fname!
	{
#if defined(MSWIN)
	    /*
	     * set full pathname for swap file now, because a ":!cd dir" may
	     * change directory without us knowing it.
	     */
	    mf_fullname(mfp);
#endif
	    ml_upd_block0(buf, UB_SAME_DIR);

	    // Flush block zero, so others can read it
	    if (mf_sync(mfp, MFS_ZERO) == OK)
	    {
		// Mark all blocks that should be in the swapfile as dirty.
		// Needed for when the 'swapfile' option was reset, so that
		// the swap file was deleted, and then on again.
		mf_set_dirty(mfp);
		break;
	    }
	    // Writing block 0 failed: close the file and try another dir
	    mf_close_file(buf, FALSE);
	}
    }

    if (*p_dir != NUL && mfp->mf_fname == NULL)
    {
	need_wait_return = TRUE;	// call wait_return later
	++no_wait_return;
	(void)semsg(_("E303: Unable to open swap file for \"%s\", recovery impossible"),
		    buf_spname(buf) != NULL ? buf_spname(buf) : buf->b_fname);
	--no_wait_return;
    }

    // don't try to open a swap file again
    buf->b_may_swap = FALSE;
}

/*
 * If still need to create a swap file, and starting to edit a not-readonly
 * file, or reading into an existing buffer, create a swap file now.
 */
    void
check_need_swap(
    int	    newfile)		// reading file into new buffer
{
    int old_msg_silent = msg_silent; // might be reset by an E325 message

    if (curbuf->b_may_swap && (!curbuf->b_p_ro || !newfile))
	ml_open_file(curbuf);
    msg_silent = old_msg_silent;
}

/*
 * Close memline for buffer 'buf'.
 * If 'del_file' is TRUE, delete the swap file
 */
    void
ml_close(buf_T *buf, int del_file)
{
    if (buf->b_ml.ml_mfp == NULL)		// not open
	return;
    mf_close(buf->b_ml.ml_mfp, del_file);	// close the .swp file
    if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY))
	vim_free(buf->b_ml.ml_line_ptr);
    vim_free(buf->b_ml.ml_stack);
#ifdef FEAT_BYTEOFF
    VIM_CLEAR(buf->b_ml.ml_chunksize);
#endif
    buf->b_ml.ml_mfp = NULL;

    // Reset the "recovered" flag, give the ATTENTION prompt the next time
    // this buffer is loaded.
    buf->b_flags &= ~BF_RECOVERED;
}

/*
 * Close all existing memlines and memfiles.
 * Only used when exiting.
 * When 'del_file' is TRUE, delete the memfiles.
 * But don't delete files that were ":preserve"d when we are POSIX compatible.
 */
    void
ml_close_all(int del_file)
{
    buf_T	*buf;

    FOR_ALL_BUFFERS(buf)
	ml_close(buf, del_file && ((buf->b_flags & BF_PRESERVED) == 0
				 || vim_strchr(p_cpo, CPO_PRESERVE) == NULL));
#ifdef FEAT_SPELL
    spell_delete_wordlist();	// delete the internal wordlist
#endif
#ifdef TEMPDIRNAMES
    vim_deltempdir();		// delete created temp directory
#endif
}

/*
 * Close all memfiles for not modified buffers.
 * Only use just before exiting!
 */
    void
ml_close_notmod(void)
{
    buf_T	*buf;

    FOR_ALL_BUFFERS(buf)
	if (!bufIsChanged(buf))
	    ml_close(buf, TRUE);    // close all not-modified buffers
}

/*
 * Update the timestamp in the .swp file.
 * Used when the file has been written.
 */
    void
ml_timestamp(buf_T *buf)
{
    ml_upd_block0(buf, UB_FNAME);
}

/*
 * Return FAIL when the ID of "b0p" is wrong.
 */
    static int
ml_check_b0_id(ZERO_BL *b0p)
{
    if (b0p->b0_id[0] != BLOCK0_ID0
	    || (b0p->b0_id[1] != BLOCK0_ID1
		&& b0p->b0_id[1] != BLOCK0_ID1_C0
		&& b0p->b0_id[1] != BLOCK0_ID1_C1
		&& b0p->b0_id[1] != BLOCK0_ID1_C2)
	    )
	return FAIL;
    return OK;
}

/*
 * Update the timestamp or the B0_SAME_DIR flag of the .swp file.
 */
    static void
ml_upd_block0(buf_T *buf, upd_block0_T what)
{
    memfile_T	*mfp;
    bhdr_T	*hp;
    ZERO_BL	*b0p;

    mfp = buf->b_ml.ml_mfp;
    if (mfp == NULL)
	return;
    hp = mf_get(mfp, (blocknr_T)0, 1);
    if (hp == NULL)
    {
#ifdef FEAT_CRYPT
	// Possibly update the seed in the memfile before there is a block0.
	if (what == UB_CRYPT)
	    ml_set_mfp_crypt(buf);
#endif
	return;
    }

    b0p = (ZERO_BL *)(hp->bh_data);
    if (ml_check_b0_id(b0p) == FAIL)
	iemsg(_("E304: ml_upd_block0(): Didn't get block 0??"));
    else
    {
	if (what == UB_FNAME)
	    set_b0_fname(b0p, buf);
#ifdef FEAT_CRYPT
	else if (what == UB_CRYPT)
	    ml_set_b0_crypt(buf, b0p);
#endif
	else // what == UB_SAME_DIR
	    set_b0_dir_flag(b0p, buf);
    }
    mf_put(mfp, hp, TRUE, FALSE);
}

/*
 * Write file name and timestamp into block 0 of a swap file.
 * Also set buf->b_mtime.
 * Don't use NameBuff[]!!!
 */
    static void
set_b0_fname(ZERO_BL *b0p, buf_T *buf)
{
    stat_T	st;

    if (buf->b_ffname == NULL)
	b0p->b0_fname[0] = NUL;
    else
    {
#if defined(MSWIN) || defined(AMIGA)
	// Systems that cannot translate "~user" back into a path: copy the
	// file name unmodified.  Do use slashes instead of backslashes for
	// portability.
	vim_strncpy(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE_CRYPT - 1);
# ifdef BACKSLASH_IN_FILENAME
	forward_slash(b0p->b0_fname);
# endif
#else
	size_t	flen, ulen;
	char_u	uname[B0_UNAME_SIZE];

	/*
	 * For a file under the home directory of the current user, we try to
	 * replace the home directory path with "~user". This helps when
	 * editing the same file on different machines over a network.
	 * First replace home dir path with "~/" with home_replace().
	 * Then insert the user name to get "~user/".
	 */
	home_replace(NULL, buf->b_ffname, b0p->b0_fname,
						   B0_FNAME_SIZE_CRYPT, TRUE);
	if (b0p->b0_fname[0] == '~')
	{
	    flen = STRLEN(b0p->b0_fname);
	    // If there is no user name or it is too long, don't use "~/"
	    if (get_user_name(uname, B0_UNAME_SIZE) == FAIL
		   || (ulen = STRLEN(uname)) + flen > B0_FNAME_SIZE_CRYPT - 1)
		vim_strncpy(b0p->b0_fname, buf->b_ffname,
						     B0_FNAME_SIZE_CRYPT - 1);
	    else
	    {
		mch_memmove(b0p->b0_fname + ulen + 1, b0p->b0_fname + 1, flen);
		mch_memmove(b0p->b0_fname + 1, uname, ulen);
	    }
	}
#endif
	if (mch_stat((char *)buf->b_ffname, &st) >= 0)
	{
	    long_to_char((long)st.st_mtime, b0p->b0_mtime);
#ifdef CHECK_INODE
	    long_to_char((long)st.st_ino, b0p->b0_ino);
#endif
	    buf_store_time(buf, &st, buf->b_ffname);
	    buf->b_mtime_read = buf->b_mtime;
	}
	else
	{
	    long_to_char(0L, b0p->b0_mtime);
#ifdef CHECK_INODE
	    long_to_char(0L, b0p->b0_ino);
#endif
	    buf->b_mtime = 0;
	    buf->b_mtime_read = 0;
	    buf->b_orig_size = 0;
	    buf->b_orig_mode = 0;
	}
    }

    // Also add the 'fileencoding' if there is room.
    add_b0_fenc(b0p, curbuf);
}

/*
 * Update the B0_SAME_DIR flag of the swap file.  It's set if the file and the
 * swapfile for "buf" are in the same directory.
 * This is fail safe: if we are not sure the directories are equal the flag is
 * not set.
 */
    static void
set_b0_dir_flag(ZERO_BL *b0p, buf_T *buf)
{
    if (same_directory(buf->b_ml.ml_mfp->mf_fname, buf->b_ffname))
	b0p->b0_flags |= B0_SAME_DIR;
    else
	b0p->b0_flags &= ~B0_SAME_DIR;
}

/*
 * When there is room, add the 'fileencoding' to block zero.
 */
    static void
add_b0_fenc(
    ZERO_BL	*b0p,
    buf_T	*buf)
{
    int		n;
    int		size = B0_FNAME_SIZE_NOCRYPT;

#ifdef FEAT_CRYPT
    // Without encryption use the same offset as in Vim 7.2 to be compatible.
    // With encryption it's OK to move elsewhere, the swap file is not
    // compatible anyway.
    if (*buf->b_p_key != NUL)
	size = B0_FNAME_SIZE_CRYPT;
#endif

    n = (int)STRLEN(buf->b_p_fenc);
    if ((int)STRLEN(b0p->b0_fname) + n + 1 > size)
	b0p->b0_flags &= ~B0_HAS_FENC;
    else
    {
	mch_memmove((char *)b0p->b0_fname + size - n,
					    (char *)buf->b_p_fenc, (size_t)n);
	*(b0p->b0_fname + size - n - 1) = NUL;
	b0p->b0_flags |= B0_HAS_FENC;
    }
}


/*
 * Try to recover curbuf from the .swp file.
 * If "checkext" is TRUE, check the extension and detect whether it is
 * a swap file.
 */
    void
ml_recover(int checkext)
{
    buf_T	*buf = NULL;
    memfile_T	*mfp = NULL;
    char_u	*fname;
    char_u	*fname_used = NULL;
    bhdr_T	*hp = NULL;
    ZERO_BL	*b0p;
    int		b0_ff;
    char_u	*b0_fenc = NULL;
#ifdef FEAT_CRYPT
    int		b0_cm = -1;
#endif
    PTR_BL	*pp;
    DATA_BL	*dp;
    infoptr_T	*ip;
    blocknr_T	bnum;
    int		page_count;
    stat_T	org_stat, swp_stat;
    int		len;
    int		directly;
    linenr_T	lnum;
    char_u	*p;
    int		i;
    long	error;
    int		cannot_open;
    linenr_T	line_count;
    int		has_error;
    int		idx;
    int		top;
    int		txt_start;
    off_T	size;
    int		called_from_main;
    int		serious_error = TRUE;
    long	mtime;
    int		attr;
    int		orig_file_status = NOTDONE;

    recoverymode = TRUE;
    called_from_main = (curbuf->b_ml.ml_mfp == NULL);
    attr = HL_ATTR(HLF_E);

    /*
     * If the file name ends in ".s[a-w][a-z]" we assume this is the swap file.
     * Otherwise a search is done to find the swap file(s).
     */
    fname = curbuf->b_fname;
    if (fname == NULL)		    // When there is no file name
	fname = (char_u *)"";
    len = (int)STRLEN(fname);
    if (checkext && len >= 4 &&
#if defined(VMS)
	    STRNICMP(fname + len - 4, "_s", 2)
#else
	    STRNICMP(fname + len - 4, ".s", 2)
#endif
						== 0
		&& vim_strchr((char_u *)"abcdefghijklmnopqrstuvw",
					   TOLOWER_ASC(fname[len - 2])) != NULL
		&& ASCII_ISALPHA(fname[len - 1]))
    {
	directly = TRUE;
	fname_used = vim_strsave(fname); // make a copy for mf_open()
    }
    else
    {
	directly = FALSE;

	// count the number of matching swap files
	len = recover_names(fname, FALSE, 0, NULL);
	if (len == 0)		    // no swap files found
	{
	    semsg(_("E305: No swap file found for %s"), fname);
	    goto theend;
	}
	if (len == 1)		    // one swap file found, use it
	    i = 1;
	else			    // several swap files found, choose
	{
	    // list the names of the swap files
	    (void)recover_names(fname, TRUE, 0, NULL);
	    msg_putchar('\n');
	    msg_puts(_("Enter number of swap file to use (0 to quit): "));
	    i = get_number(FALSE, NULL);
	    if (i < 1 || i > len)
		goto theend;
	}
	// get the swap file name that will be used
	(void)recover_names(fname, FALSE, i, &fname_used);
    }
    if (fname_used == NULL)
	goto theend;			// out of memory

    // When called from main() still need to initialize storage structure
    if (called_from_main && ml_open(curbuf) == FAIL)
	getout(1);

    /*
     * Allocate a buffer structure for the swap file that is used for recovery.
     * Only the memline and crypt information in it are really used.
     */
    buf = ALLOC_ONE(buf_T);
    if (buf == NULL)
	goto theend;

    /*
     * init fields in memline struct
     */
    buf->b_ml.ml_stack_size = 0;	// no stack yet
    buf->b_ml.ml_stack = NULL;		// no stack yet
    buf->b_ml.ml_stack_top = 0;		// nothing in the stack
    buf->b_ml.ml_line_lnum = 0;		// no cached line
    buf->b_ml.ml_locked = NULL;		// no locked block
    buf->b_ml.ml_flags = 0;
#ifdef FEAT_CRYPT
    buf->b_p_key = empty_option;
    buf->b_p_cm = empty_option;
#endif

    /*
     * open the memfile from the old swap file
     */
    p = vim_strsave(fname_used); // save "fname_used" for the message:
				 // mf_open() will consume "fname_used"!
    mfp = mf_open(fname_used, O_RDONLY);
    fname_used = p;
    if (mfp == NULL || mfp->mf_fd < 0)
    {
	if (fname_used != NULL)
	    semsg(_("E306: Cannot open %s"), fname_used);
	goto theend;
    }
    buf->b_ml.ml_mfp = mfp;
#ifdef FEAT_CRYPT
    mfp->mf_buffer = buf;
#endif

    /*
     * The page size set in mf_open() might be different from the page size
     * used in the swap file, we must get it from block 0.  But to read block
     * 0 we need a page size.  Use the minimal size for block 0 here, it will
     * be set to the real value below.
     */
    mfp->mf_page_size = MIN_SWAP_PAGE_SIZE;

    /*
     * try to read block 0
     */
    if ((hp = mf_get(mfp, (blocknr_T)0, 1)) == NULL)
    {
	msg_start();
	msg_puts_attr(_("Unable to read block 0 from "), attr | MSG_HIST);
	msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
	msg_puts_attr(_("\nMaybe no changes were made or Vim did not update the swap file."),
		attr | MSG_HIST);
	msg_end();
	goto theend;
    }
    b0p = (ZERO_BL *)(hp->bh_data);
    if (STRNCMP(b0p->b0_version, "VIM 3.0", 7) == 0)
    {
	msg_start();
	msg_outtrans_attr(mfp->mf_fname, MSG_HIST);
	msg_puts_attr(_(" cannot be used with this version of Vim.\n"),
								    MSG_HIST);
	msg_puts_attr(_("Use Vim version 3.0.\n"), MSG_HIST);
	msg_end();
	goto theend;
    }
    if (ml_check_b0_id(b0p) == FAIL)
    {
	semsg(_("E307: %s does not look like a Vim swap file"), mfp->mf_fname);
	goto theend;
    }
    if (b0_magic_wrong(b0p))
    {
	msg_start();
	msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
#if defined(MSWIN)
	if (STRNCMP(b0p->b0_hname, "PC ", 3) == 0)
	    msg_puts_attr(_(" cannot be used with this version of Vim.\n"),
							     attr | MSG_HIST);
	else
#endif
	    msg_puts_attr(_(" cannot be used on this computer.\n"),
							     attr | MSG_HIST);
	msg_puts_attr(_("The file was created on "), attr | MSG_HIST);
	// avoid going past the end of a corrupted hostname
	b0p->b0_fname[0] = NUL;
	msg_puts_attr((char *)b0p->b0_hname, attr | MSG_HIST);
	msg_puts_attr(_(",\nor the file has been damaged."), attr | MSG_HIST);
	msg_end();
	goto theend;
    }

#ifdef FEAT_CRYPT
    for (i = 0; i < (int)(sizeof(id1_codes) / sizeof(int)); ++i)
	if (id1_codes[i] == b0p->b0_id[1])
	    b0_cm = i;
    if (b0_cm > 0)
	mch_memmove(mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
    crypt_set_cm_option(buf, b0_cm < 0 ? 0 : b0_cm);
#else
    if (b0p->b0_id[1] != BLOCK0_ID1)
    {
	semsg(_("E833: %s is encrypted and this version of Vim does not support encryption"), mfp->mf_fname);
	goto theend;
    }
#endif

    /*
     * If we guessed the wrong page size, we have to recalculate the
     * highest block number in the file.
     */
    if (mfp->mf_page_size != (unsigned)char_to_long(b0p->b0_page_size))
    {
	unsigned previous_page_size = mfp->mf_page_size;

	mf_new_page_size(mfp, (unsigned)char_to_long(b0p->b0_page_size));
	if (mfp->mf_page_size < previous_page_size)
	{
	    msg_start();
	    msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
	    msg_puts_attr(_(" has been damaged (page size is smaller than minimum value).\n"),
			attr | MSG_HIST);
	    msg_end();
	    goto theend;
	}
	if ((size = vim_lseek(mfp->mf_fd, (off_T)0L, SEEK_END)) <= 0)
	    mfp->mf_blocknr_max = 0;	    // no file or empty file
	else
	    mfp->mf_blocknr_max = (blocknr_T)(size / mfp->mf_page_size);
	mfp->mf_infile_count = mfp->mf_blocknr_max;

	// need to reallocate the memory used to store the data
	p = alloc(mfp->mf_page_size);
	if (p == NULL)
	    goto theend;
	mch_memmove(p, hp->bh_data, previous_page_size);
	vim_free(hp->bh_data);
	hp->bh_data = p;
	b0p = (ZERO_BL *)(hp->bh_data);
    }

    /*
     * If .swp file name given directly, use name from swap file for buffer.
     */
    if (directly)
    {
	expand_env(b0p->b0_fname, NameBuff, MAXPATHL);
	if (setfname(curbuf, NameBuff, NULL, TRUE) == FAIL)
	    goto theend;
    }

    home_replace(NULL, mfp->mf_fname, NameBuff, MAXPATHL, TRUE);
    smsg(_("Using swap file \"%s\""), NameBuff);

    if (buf_spname(curbuf) != NULL)
	vim_strncpy(NameBuff, buf_spname(curbuf), MAXPATHL - 1);
    else
	home_replace(NULL, curbuf->b_ffname, NameBuff, MAXPATHL, TRUE);
    smsg(_("Original file \"%s\""), NameBuff);
    msg_putchar('\n');

    /*
     * check date of swap file and original file
     */
    mtime = char_to_long(b0p->b0_mtime);
    if (curbuf->b_ffname != NULL
	    && mch_stat((char *)curbuf->b_ffname, &org_stat) != -1
	    && ((mch_stat((char *)mfp->mf_fname, &swp_stat) != -1
		    && org_stat.st_mtime > swp_stat.st_mtime)
		|| org_stat.st_mtime != mtime))
	emsg(_("E308: Warning: Original file may have been changed"));
    out_flush();

    // Get the 'fileformat' and 'fileencoding' from block zero.
    b0_ff = (b0p->b0_flags & B0_FF_MASK);
    if (b0p->b0_flags & B0_HAS_FENC)
    {
	int fnsize = B0_FNAME_SIZE_NOCRYPT;

#ifdef FEAT_CRYPT
	// Use the same size as in add_b0_fenc().
	if (b0p->b0_id[1] != BLOCK0_ID1)
	    fnsize = B0_FNAME_SIZE_CRYPT;
#endif
	for (p = b0p->b0_fname + fnsize; p > b0p->b0_fname && p[-1] != NUL; --p)
	    ;
	b0_fenc = vim_strnsave(p, (int)(b0p->b0_fname + fnsize - p));
    }

    mf_put(mfp, hp, FALSE, FALSE);	// release block 0
    hp = NULL;

    /*
     * Now that we are sure that the file is going to be recovered, clear the
     * contents of the current buffer.
     */
    while (!(curbuf->b_ml.ml_flags & ML_EMPTY))
	ml_delete((linenr_T)1, FALSE);

    /*
     * Try reading the original file to obtain the values of 'fileformat',
     * 'fileencoding', etc.  Ignore errors.  The text itself is not used.
     * When the file is encrypted the user is asked to enter the key.
     */
    if (curbuf->b_ffname != NULL)
	orig_file_status = readfile(curbuf->b_ffname, NULL, (linenr_T)0,
			      (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW);

#ifdef FEAT_CRYPT
    if (b0_cm >= 0)
    {
	// Need to ask the user for the crypt key.  If this fails we continue
	// without a key, will probably get garbage text.
	if (*curbuf->b_p_key != NUL)
	{
	    smsg(_("Swap file is encrypted: \"%s\""), fname_used);
	    msg_puts(_("\nIf you entered a new crypt key but did not write the text file,"));
	    msg_puts(_("\nenter the new crypt key."));
	    msg_puts(_("\nIf you wrote the text file after changing the crypt key press enter"));
	    msg_puts(_("\nto use the same key for text file and swap file"));
	}
	else
	    smsg(_(need_key_msg), fname_used);
	buf->b_p_key = crypt_get_key(FALSE, FALSE);
	if (buf->b_p_key == NULL)
	    buf->b_p_key = curbuf->b_p_key;
	else if (*buf->b_p_key == NUL)
	{
	    vim_free(buf->b_p_key);
	    buf->b_p_key = curbuf->b_p_key;
	}
	if (buf->b_p_key == NULL)
	    buf->b_p_key = empty_option;
    }
#endif

    // Use the 'fileformat' and 'fileencoding' as stored in the swap file.
    if (b0_ff != 0)
	set_fileformat(b0_ff - 1, OPT_LOCAL);
    if (b0_fenc != NULL)
    {
	set_option_value((char_u *)"fenc", 0L, b0_fenc, OPT_LOCAL);
	vim_free(b0_fenc);
    }
    unchanged(curbuf, TRUE, TRUE);

    bnum = 1;		// start with block 1
    page_count = 1;	// which is 1 page
    lnum = 0;		// append after line 0 in curbuf
    line_count = 0;
    idx = 0;		// start with first index in block 1
    error = 0;
    buf->b_ml.ml_stack_top = 0;
    buf->b_ml.ml_stack = NULL;
    buf->b_ml.ml_stack_size = 0;	// no stack yet

    if (curbuf->b_ffname == NULL)
	cannot_open = TRUE;
    else
	cannot_open = FALSE;

    serious_error = FALSE;
    for ( ; !got_int; line_breakcheck())
    {
	if (hp != NULL)
	    mf_put(mfp, hp, FALSE, FALSE);	// release previous block

	/*
	 * get block
	 */
	if ((hp = mf_get(mfp, (blocknr_T)bnum, page_count)) == NULL)
	{
	    if (bnum == 1)
	    {
		semsg(_("E309: Unable to read block 1 from %s"), mfp->mf_fname);
		goto theend;
	    }
	    ++error;
	    ml_append(lnum++, (char_u *)_("???MANY LINES MISSING"),
							    (colnr_T)0, TRUE);
	}
	else		// there is a block
	{
	    pp = (PTR_BL *)(hp->bh_data);
	    if (pp->pb_id == PTR_ID)		// it is a pointer block
	    {
		// check line count when using pointer block first time
		if (idx == 0 && line_count != 0)
		{
		    for (i = 0; i < (int)pp->pb_count; ++i)
			line_count -= pp->pb_pointer[i].pe_line_count;
		    if (line_count != 0)
		    {
			++error;
			ml_append(lnum++, (char_u *)_("???LINE COUNT WRONG"),
							    (colnr_T)0, TRUE);
		    }
		}

		if (pp->pb_count == 0)
		{
		    ml_append(lnum++, (char_u *)_("???EMPTY BLOCK"),
							    (colnr_T)0, TRUE);
		    ++error;
		}
		else if (idx < (int)pp->pb_count)	// go a block deeper
		{
		    if (pp->pb_pointer[idx].pe_bnum < 0)
		    {
			/*
			 * Data block with negative block number.
			 * Try to read lines from the original file.
			 * This is slow, but it works.
			 */
			if (!cannot_open)
			{
			    line_count = pp->pb_pointer[idx].pe_line_count;
			    if (readfile(curbuf->b_ffname, NULL, lnum,
					pp->pb_pointer[idx].pe_old_lnum - 1,
					line_count, NULL, 0) != OK)
				cannot_open = TRUE;
			    else
				lnum += line_count;
			}
			if (cannot_open)
			{
			    ++error;
			    ml_append(lnum++, (char_u *)_("???LINES MISSING"),
							    (colnr_T)0, TRUE);
			}
			++idx;	    // get same block again for next index
			continue;
		    }

		    /*
		     * going one block deeper in the tree
		     */
		    if ((top = ml_add_stack(buf)) < 0)	// new entry in stack
		    {
			++error;
			break;		    // out of memory
		    }
		    ip = &(buf->b_ml.ml_stack[top]);
		    ip->ip_bnum = bnum;
		    ip->ip_index = idx;

		    bnum = pp->pb_pointer[idx].pe_bnum;
		    line_count = pp->pb_pointer[idx].pe_line_count;
		    page_count = pp->pb_pointer[idx].pe_page_count;
		    idx = 0;
		    continue;
		}
	    }
	    else	    // not a pointer block
	    {
		dp = (DATA_BL *)(hp->bh_data);
		if (dp->db_id != DATA_ID)	// block id wrong
		{
		    if (bnum == 1)
		    {
			semsg(_("E310: Block 1 ID wrong (%s not a .swp file?)"),
							       mfp->mf_fname);
			goto theend;
		    }
		    ++error;
		    ml_append(lnum++, (char_u *)_("???BLOCK MISSING"),
							    (colnr_T)0, TRUE);
		}
		else
		{
		    /*
		     * it is a data block
		     * Append all the lines in this block
		     */
		    has_error = FALSE;
			/*
			 * check length of block
			 * if wrong, use length in pointer block
			 */
		    if (page_count * mfp->mf_page_size != dp->db_txt_end)
		    {
			ml_append(lnum++, (char_u *)_("??? from here until ???END lines may be messed up"),
							    (colnr_T)0, TRUE);
			++error;
			has_error = TRUE;
			dp->db_txt_end = page_count * mfp->mf_page_size;
		    }

			// make sure there is a NUL at the end of the block
		    *((char_u *)dp + dp->db_txt_end - 1) = NUL;

			/*
			 * check number of lines in block
			 * if wrong, use count in data block
			 */
		    if (line_count != dp->db_line_count)
		    {
			ml_append(lnum++, (char_u *)_("??? from here until ???END lines may have been inserted/deleted"),
							    (colnr_T)0, TRUE);
			++error;
			has_error = TRUE;
		    }

		    for (i = 0; i < dp->db_line_count; ++i)
		    {
			txt_start = (dp->db_index[i] & DB_INDEX_MASK);
			if (txt_start <= (int)HEADER_SIZE
					  || txt_start >= (int)dp->db_txt_end)
			{
			    p = (char_u *)"???";
			    ++error;
			}
			else
			    p = (char_u *)dp + txt_start;
			ml_append(lnum++, p, (colnr_T)0, TRUE);
		    }
		    if (has_error)
			ml_append(lnum++, (char_u *)_("???END"),
							    (colnr_T)0, TRUE);
		}
	    }
	}

	if (buf->b_ml.ml_stack_top == 0)	// finished
	    break;

	/*
	 * go one block up in the tree
	 */
	ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]);
	bnum = ip->ip_bnum;
	idx = ip->ip_index + 1;	    // go to next index
	page_count = 1;
    }

    /*
     * Compare the buffer contents with the original file.  When they differ
     * set the 'modified' flag.
     * Lines 1 - lnum are the new contents.
     * Lines lnum + 1 to ml_line_count are the original contents.
     * Line ml_line_count + 1 in the dummy empty line.
     */
    if (orig_file_status != OK || curbuf->b_ml.ml_line_count != lnum * 2 + 1)
    {
	// Recovering an empty file results in two lines and the first line is
	// empty.  Don't set the modified flag then.
	if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL))
	{
	    changed_internal();
	    ++CHANGEDTICK(curbuf);
	}
    }
    else
    {
	for (idx = 1; idx <= lnum; ++idx)
	{
	    // Need to copy one line, fetching the other one may flush it.
	    p = vim_strsave(ml_get(idx));
	    i = STRCMP(p, ml_get(idx + lnum));
	    vim_free(p);
	    if (i != 0)
	    {
		changed_internal();
		++CHANGEDTICK(curbuf);
		break;
	    }
	}
    }

    /*
     * Delete the lines from the original file and the dummy line from the
     * empty buffer.  These will now be after the last line in the buffer.
     */
    while (curbuf->b_ml.ml_line_count > lnum
				       && !(curbuf->b_ml.ml_flags & ML_EMPTY))
	ml_delete(curbuf->b_ml.ml_line_count, FALSE);
    curbuf->b_flags |= BF_RECOVERED;

    recoverymode = FALSE;
    if (got_int)
	emsg(_("E311: Recovery Interrupted"));
    else if (error)
    {
	++no_wait_return;
	msg(">>>>>>>>>>>>>");
	emsg(_("E312: Errors detected while recovering; look for lines starting with ???"));
	--no_wait_return;
	msg(_("See \":help E312\" for more information."));
	msg(">>>>>>>>>>>>>");
    }
    else
    {
	if (curbuf->b_changed)
	{
	    msg(_("Recovery completed. You should check if everything is OK."));
	    msg_puts(_("\n(You might want to write out this file under another name\n"));
	    msg_puts(_("and run diff with the original file to check for changes)"));
	}
	else
	    msg(_("Recovery completed. Buffer contents equals file contents."));
	msg_puts(_("\nYou may want to delete the .swp file now.\n\n"));
	cmdline_row = msg_row;
    }
#ifdef FEAT_CRYPT
    if (*buf->b_p_key != NUL && STRCMP(curbuf->b_p_key, buf->b_p_key) != 0)
    {
	msg_puts(_("Using crypt key from swap file for the text file.\n"));
	set_option_value((char_u *)"key", 0L, buf->b_p_key, OPT_LOCAL);
    }
#endif
    redraw_curbuf_later(NOT_VALID);

theend:
    vim_free(fname_used);
    recoverymode = FALSE;
    if (mfp != NULL)
    {
	if (hp != NULL)
	    mf_put(mfp, hp, FALSE, FALSE);
	mf_close(mfp, FALSE);	    // will also vim_free(mfp->mf_fname)
    }
    if (buf != NULL)
    {
#ifdef FEAT_CRYPT
	if (buf->b_p_key != curbuf->b_p_key)
	    free_string_option(buf->b_p_key);
	free_string_option(buf->b_p_cm);
#endif
	vim_free(buf->b_ml.ml_stack);
	vim_free(buf);
    }
    if (serious_error && called_from_main)
	ml_close(curbuf, TRUE);
    else
    {
	apply_autocmds(EVENT_BUFREADPOST, NULL, curbuf->b_fname, FALSE, curbuf);
	apply_autocmds(EVENT_BUFWINENTER, NULL, curbuf->b_fname, FALSE, curbuf);
    }
    return;
}

/*
 * Find the names of swap files in current directory and the directory given
 * with the 'directory' option.
 *
 * Used to:
 * - list the swap files for "vim -r"
 * - count the number of swap files when recovering
 * - list the swap files when recovering
 * - find the name of the n'th swap file when recovering
 */
    int
recover_names(
    char_u	*fname,		// base for swap file name
    int		list,		// when TRUE, list the swap file names
    int		nr,		// when non-zero, return nr'th swap file name
    char_u	**fname_out)	// result when "nr" > 0
{
    int		num_names;
    char_u	*(names[6]);
    char_u	*tail;
    char_u	*p;
    int		num_files;
    int		file_count = 0;
    char_u	**files;
    int		i;
    char_u	*dirp;
    char_u	*dir_name;
    char_u	*fname_res = NULL;
#ifdef HAVE_READLINK
    char_u	fname_buf[MAXPATHL];
#endif

    if (fname != NULL)
    {
#ifdef HAVE_READLINK
	// Expand symlink in the file name, because the swap file is created
	// with the actual file instead of with the symlink.
	if (resolve_symlink(fname, fname_buf) == OK)
	    fname_res = fname_buf;
	else
#endif
	    fname_res = fname;
    }

    if (list)
    {
	// use msg() to start the scrolling properly
	msg(_("Swap files found:"));
	msg_putchar('\n');
    }

    /*
     * Do the loop for every directory in 'directory'.
     * First allocate some memory to put the directory name in.
     */
    dir_name = alloc(STRLEN(p_dir) + 1);
    dirp = p_dir;
    while (dir_name != NULL && *dirp)
    {
	/*
	 * Isolate a directory name from *dirp and put it in dir_name (we know
	 * it is large enough, so use 31000 for length).
	 * Advance dirp to next directory name.
	 */
	(void)copy_option_part(&dirp, dir_name, 31000, ",");

	if (dir_name[0] == '.' && dir_name[1] == NUL)	// check current dir
	{
	    if (fname == NULL)
	    {
#ifdef VMS
		names[0] = vim_strsave((char_u *)"*_sw%");
#else
		names[0] = vim_strsave((char_u *)"*.sw?");
#endif
#if defined(UNIX) || defined(MSWIN)
		// For Unix names starting with a dot are special.  MS-Windows
		// supports this too, on some file systems.
		names[1] = vim_strsave((char_u *)".*.sw?");
		names[2] = vim_strsave((char_u *)".sw?");
		num_names = 3;
#else
# ifdef VMS
		names[1] = vim_strsave((char_u *)".*_sw%");
		num_names = 2;
# else
		num_names = 1;
# endif
#endif
	    }
	    else
		num_names = recov_file_names(names, fname_res, TRUE);
	}
	else			    // check directory dir_name
	{
	    if (fname == NULL)
	    {
#ifdef VMS
		names[0] = concat_fnames(dir_name, (char_u *)"*_sw%", TRUE);
#else
		names[0] = concat_fnames(dir_name, (char_u *)"*.sw?", TRUE);
#endif
#if defined(UNIX) || defined(MSWIN)
		// For Unix names starting with a dot are special.  MS-Windows
		// supports this too, on some file systems.
		names[1] = concat_fnames(dir_name, (char_u *)".*.sw?", TRUE);
		names[2] = concat_fnames(dir_name, (char_u *)".sw?", TRUE);
		num_names = 3;
#else
# ifdef VMS
		names[1] = concat_fnames(dir_name, (char_u *)".*_sw%", TRUE);
		num_names = 2;
# else
		num_names = 1;
# endif
#endif
	    }
	    else
	    {
#if defined(UNIX) || defined(MSWIN)
		int	len = (int)STRLEN(dir_name);

		p = dir_name + len;
		if (after_pathsep(dir_name, p) && len > 1 && p[-1] == p[-2])
		{
		    // Ends with '//', Use Full path for swap name
		    tail = make_percent_swname(dir_name, fname_res);
		}
		else
#endif
		{
		    tail = gettail(fname_res);
		    tail = concat_fnames(dir_name, tail, TRUE);
		}
		if (tail == NULL)
		    num_names = 0;
		else
		{
		    num_names = recov_file_names(names, tail, FALSE);
		    vim_free(tail);
		}
	    }
	}

	// check for out-of-memory
	for (i = 0; i < num_names; ++i)
	{
	    if (names[i] == NULL)
	    {
		for (i = 0; i < num_names; ++i)
		    vim_free(names[i]);
		num_names = 0;
	    }
	}
	if (num_names == 0)
	    num_files = 0;
	else if (expand_wildcards(num_names, names, &num_files, &files,
			    EW_NOTENV|EW_KEEPALL|EW_FILE|EW_SILENT) == FAIL)
	    num_files = 0;

	/*
	 * When no swap file found, wildcard expansion might have failed (e.g.
	 * not able to execute the shell).
	 * Try finding a swap file by simply adding ".swp" to the file name.
	 */
	if (*dirp == NUL && file_count + num_files == 0 && fname != NULL)
	{
	    stat_T	    st;
	    char_u	    *swapname;

	    swapname = modname(fname_res,
#if defined(VMS)
			       (char_u *)"_swp", FALSE
#else
			       (char_u *)".swp", TRUE
#endif
			      );
	    if (swapname != NULL)
	    {
		if (mch_stat((char *)swapname, &st) != -1)    // It exists!
		{
		    files = ALLOC_ONE(char_u *);
		    if (files != NULL)
		    {
			files[0] = swapname;
			swapname = NULL;
			num_files = 1;
		    }
		}
		vim_free(swapname);
	    }
	}

	/*
	 * remove swapfile name of the current buffer, it must be ignored
	 */
	if (curbuf->b_ml.ml_mfp != NULL
			       && (p = curbuf->b_ml.ml_mfp->mf_fname) != NULL)
	{
	    for (i = 0; i < num_files; ++i)
		// Do not expand wildcards, on windows would try to expand
		// "%tmp%" in "%tmp%file".
		if (fullpathcmp(p, files[i], TRUE, FALSE) & FPC_SAME)
		{
		    // Remove the name from files[i].  Move further entries
		    // down.  When the array becomes empty free it here, since
		    // FreeWild() won't be called below.
		    vim_free(files[i]);
		    if (--num_files == 0)
			vim_free(files);
		    else
			for ( ; i < num_files; ++i)
			    files[i] = files[i + 1];
		}
	}
	if (nr > 0)
	{
	    file_count += num_files;
	    if (nr <= file_count)
	    {
		*fname_out = vim_strsave(
				      files[nr - 1 + num_files - file_count]);
		dirp = (char_u *)"";		    // stop searching
	    }
	}
	else if (list)
	{
	    if (dir_name[0] == '.' && dir_name[1] == NUL)
	    {
		if (fname == NULL)
		    msg_puts(_("   In current directory:\n"));
		else
		    msg_puts(_("   Using specified name:\n"));
	    }
	    else
	    {
		msg_puts(_("   In directory "));
		msg_home_replace(dir_name);
		msg_puts(":\n");
	    }

	    if (num_files)
	    {
		for (i = 0; i < num_files; ++i)
		{
		    // print the swap file name
		    msg_outnum((long)++file_count);
		    msg_puts(".    ");
		    msg_puts((char *)gettail(files[i]));
		    msg_putchar('\n');
		    (void)swapfile_info(files[i]);
		}
	    }
	    else
		msg_puts(_("      -- none --\n"));
	    out_flush();
	}
	else
	    file_count += num_files;

	for (i = 0; i < num_names; ++i)
	    vim_free(names[i]);
	if (num_files > 0)
	    FreeWild(num_files, files);
    }
    vim_free(dir_name);
    return file_count;
}

#if defined(UNIX) || defined(MSWIN) || defined(PROTO)
/*
 * Need _very_ long file names.
 * Append the full path to name with path separators made into percent
 * signs, to dir. An unnamed buffer is handled as "" (<currentdir>/"")
 */
    char_u *
make_percent_swname(char_u *dir, char_u *name)
{
    char_u *d = NULL, *s, *f;

    f = fix_fname(name != NULL ? name : (char_u *)"");
    if (f != NULL)
    {
	s = alloc(STRLEN(f) + 1);
	if (s != NULL)
	{
	    STRCPY(s, f);
	    for (d = s; *d != NUL; MB_PTR_ADV(d))
		if (vim_ispathsep(*d))
		    *d = '%';
	    d = concat_fnames(dir, s, TRUE);
	    vim_free(s);
	}
	vim_free(f);
    }
    return d;
}
#endif

#if (defined(UNIX) || defined(VMS) || defined(MSWIN)) \
	&& (defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG))
# define HAVE_PROCESS_STILL_RUNNING
static int process_still_running;
#endif

#if defined(FEAT_EVAL) || defined(PROTO)
/*
 * Return information found in swapfile "fname" in dictionary "d".
 * This is used by the swapinfo() function.
 */
    void
get_b0_dict(char_u *fname, dict_T *d)
{
    int fd;
    struct block0 b0;

    if ((fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0)) >= 0)
    {
	if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0))
	{
	    if (ml_check_b0_id(&b0) == FAIL)
		dict_add_string(d, "error", (char_u *)"Not a swap file");
	    else if (b0_magic_wrong(&b0))
		dict_add_string(d, "error", (char_u *)"Magic number mismatch");
	    else
	    {
		// we have swap information
		dict_add_string_len(d, "version", b0.b0_version, 10);
		dict_add_string_len(d, "user", b0.b0_uname, B0_UNAME_SIZE);
		dict_add_string_len(d, "host", b0.b0_hname, B0_HNAME_SIZE);
		dict_add_string_len(d, "fname", b0.b0_fname, B0_FNAME_SIZE_ORG);

		dict_add_number(d, "pid", char_to_long(b0.b0_pid));
		dict_add_number(d, "mtime", char_to_long(b0.b0_mtime));
		dict_add_number(d, "dirty", b0.b0_dirty ? 1 : 0);
# ifdef CHECK_INODE
		dict_add_number(d, "inode", char_to_long(b0.b0_ino));
# endif
	    }
	}
	else
	    dict_add_string(d, "error", (char_u *)"Cannot read file");
	close(fd);
    }
    else
	dict_add_string(d, "error", (char_u *)"Cannot open file");
}
#endif

/*
 * Cache of the current timezone name as retrieved from TZ, or an empty string
 * where unset, up to 64 octets long including trailing null byte.
 */
#if defined(HAVE_LOCALTIME_R) && defined(HAVE_TZSET)
static char	tz_cache[64];
#endif

/*
 * Call either localtime(3) or localtime_r(3) from POSIX libc time.h, with the
 * latter version preferred for reentrancy.
 *
 * If we use localtime_r(3) and we have tzset(3) available, check to see if the
 * environment variable TZ has changed since the last run, and call tzset(3) to
 * update the global timezone variables if it has.  This is because the POSIX
 * standard doesn't require localtime_r(3) implementations to do that as it
 * does with localtime(3), and we don't want to call tzset(3) every time.
 */
    struct tm *
vim_localtime(
    const time_t	*timep,		// timestamp for local representation
    struct tm		*result UNUSED)	// pointer to caller return buffer
{
#ifdef HAVE_LOCALTIME_R
# ifdef HAVE_TZSET
    char		*tz;		// pointer for TZ environment var

    tz = (char *)mch_getenv((char_u *)"TZ");
    if (tz == NULL)
	tz = "";
    if (STRNCMP(tz_cache, tz, sizeof(tz_cache) - 1) != 0)
    {
	tzset();
	vim_strncpy((char_u *)tz_cache, (char_u *)tz, sizeof(tz_cache) - 1);
    }
# endif	// HAVE_TZSET
    return localtime_r(timep, result);
#else
    return localtime(timep);
#endif	// HAVE_LOCALTIME_R
}

/*
 * Replacement for ctime(), which is not safe to use.
 * Requires strftime(), otherwise returns "(unknown)".
 * If "thetime" is invalid returns "(invalid)".  Never returns NULL.
 * When "add_newline" is TRUE add a newline like ctime() does.
 * Uses a static buffer.
 */
    char *
get_ctime(time_t thetime, int add_newline)
{
    static char buf[50];
#ifdef HAVE_STRFTIME
    struct tm	tmval;
    struct tm	*curtime;

    curtime = vim_localtime(&thetime, &tmval);
    // MSVC returns NULL for an invalid value of seconds.
    if (curtime == NULL)
	vim_strncpy((char_u *)buf, (char_u *)_("(Invalid)"), sizeof(buf) - 1);
    else
    {
	(void)strftime(buf, sizeof(buf) - 1, _("%a %b %d %H:%M:%S %Y"),
								    curtime);
# ifdef MSWIN
	if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
	{
	    char_u	*to_free = NULL;
	    int		len;

	    acp_to_enc((char_u *)buf, (int)strlen(buf), &to_free, &len);
	    if (to_free != NULL)
	    {
		STRCPY(buf, to_free);
		vim_free(to_free);
	    }
	}
# endif
    }
#else
    STRCPY(buf, "(unknown)");
#endif
    if (add_newline)
	STRCAT(buf, "\n");
    return buf;
}

/*
 * Give information about an existing swap file.
 * Returns timestamp (0 when unknown).
 */
    static time_t
swapfile_info(char_u *fname)
{
    stat_T	    st;
    int		    fd;
    struct block0   b0;
#ifdef UNIX
    char_u	    uname[B0_UNAME_SIZE];
#endif

    // print the swap file date
    if (mch_stat((char *)fname, &st) != -1)
    {
#ifdef UNIX
	// print name of owner of the file
	if (mch_get_uname(st.st_uid, uname, B0_UNAME_SIZE) == OK)
	{
	    msg_puts(_("          owned by: "));
	    msg_outtrans(uname);
	    msg_puts(_("   dated: "));
	}
	else
#endif
	    msg_puts(_("             dated: "));
	msg_puts(get_ctime(st.st_mtime, TRUE));
    }
    else
	st.st_mtime = 0;

    /*
     * print the original file name
     */
    fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
    if (fd >= 0)
    {
	if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0))
	{
	    if (STRNCMP(b0.b0_version, "VIM 3.0", 7) == 0)
	    {
		msg_puts(_("         [from Vim version 3.0]"));
	    }
	    else if (ml_check_b0_id(&b0) == FAIL)
	    {
		msg_puts(_("         [does not look like a Vim swap file]"));
	    }
	    else
	    {
		msg_puts(_("         file name: "));
		if (b0.b0_fname[0] == NUL)
		    msg_puts(_("[No Name]"));
		else
		    msg_outtrans(b0.b0_fname);

		msg_puts(_("\n          modified: "));
		msg_puts(b0.b0_dirty ? _("YES") : _("no"));

		if (*(b0.b0_uname) != NUL)
		{
		    msg_puts(_("\n         user name: "));
		    msg_outtrans(b0.b0_uname);
		}

		if (*(b0.b0_hname) != NUL)
		{
		    if (*(b0.b0_uname) != NUL)
			msg_puts(_("   host name: "));
		    else
			msg_puts(_("\n         host name: "));
		    msg_outtrans(b0.b0_hname);
		}

		if (char_to_long(b0.b0_pid) != 0L)
		{
		    msg_puts(_("\n        process ID: "));
		    msg_outnum(char_to_long(b0.b0_pid));
#if defined(UNIX) || defined(MSWIN)
		    if (mch_process_running(char_to_long(b0.b0_pid)))
		    {
			msg_puts(_(" (STILL RUNNING)"));
# ifdef HAVE_PROCESS_STILL_RUNNING
			process_still_running = TRUE;
# endif
		    }
#endif
		}

		if (b0_magic_wrong(&b0))
		{
#if defined(MSWIN)
		    if (STRNCMP(b0.b0_hname, "PC ", 3) == 0)
			msg_puts(_("\n         [not usable with this version of Vim]"));
		    else
#endif
			msg_puts(_("\n         [not usable on this computer]"));
		}
	    }
	}
	else
	    msg_puts(_("         [cannot be read]"));
	close(fd);
    }
    else
	msg_puts(_("         [cannot be opened]"));
    msg_putchar('\n');

    return st.st_mtime;
}

/*
 * Return TRUE if the swap file looks OK and there are no changes, thus it can
 * be safely deleted.
 */
    static time_t
swapfile_unchanged(char_u *fname)
{
    stat_T	    st;
    int		    fd;
    struct block0   b0;
    int		    ret = TRUE;
#if defined(UNIX) || defined(MSWIN)
    long	    pid;
#endif

    // must be able to stat the swap file
    if (mch_stat((char *)fname, &st) == -1)
	return FALSE;

    // must be able to read the first block
    fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
    if (fd < 0)
	return FALSE;
    if (read_eintr(fd, &b0, sizeof(b0)) != sizeof(b0))
    {
	close(fd);
	return FALSE;
    }

    // the ID and magic number must be correct
    if (ml_check_b0_id(&b0) == FAIL|| b0_magic_wrong(&b0))
	ret = FALSE;

    // must be unchanged
    if (b0.b0_dirty)
	ret = FALSE;

#if defined(UNIX) || defined(MSWIN)
    // process must be known and not be running
    pid = char_to_long(b0.b0_pid);
    if (pid == 0L || mch_process_running(pid))
	ret = FALSE;
#endif

    // TODO: Should we check if the swap file was created on the current
    // system?  And the current user?

    close(fd);
    return ret;
}

    static int
recov_file_names(char_u **names, char_u *path, int prepend_dot)
{
    int		num_names;

    /*
     * (Win32 and Win64) never short names, but do prepend a dot.
     * (Not MS-DOS or Win32 or Win64) maybe short name, maybe not: Try both.
     * Only use the short name if it is different.
     */
    char_u	*p;
    int		i;
# ifndef MSWIN
    int	    shortname = curbuf->b_shortname;

    curbuf->b_shortname = FALSE;
# endif

    num_names = 0;

    /*
     * May also add the file name with a dot prepended, for swap file in same
     * dir as original file.
     */
    if (prepend_dot)
    {
	names[num_names] = modname(path, (char_u *)".sw?", TRUE);
	if (names[num_names] == NULL)
	    goto end;
	++num_names;
    }

    /*
     * Form the normal swap file name pattern by appending ".sw?".
     */
#ifdef VMS
    names[num_names] = concat_fnames(path, (char_u *)"_sw%", FALSE);
#else
    names[num_names] = concat_fnames(path, (char_u *)".sw?", FALSE);
#endif
    if (names[num_names] == NULL)
	goto end;
    if (num_names >= 1)	    // check if we have the same name twice
    {
	p = names[num_names - 1];
	i = (int)STRLEN(names[num_names - 1]) - (int)STRLEN(names[num_names]);
	if (i > 0)
	    p += i;	    // file name has been expanded to full path

	if (STRCMP(p, names[num_names]) != 0)
	    ++num_names;
	else
	    vim_free(names[num_names]);
    }
    else
	++num_names;

# ifndef MSWIN
    /*
     * Also try with 'shortname' set, in case the file is on a DOS filesystem.
     */
    curbuf->b_shortname = TRUE;
#ifdef VMS
    names[num_names] = modname(path, (char_u *)"_sw%", FALSE);
#else
    names[num_names] = modname(path, (char_u *)".sw?", FALSE);
#endif
    if (names[num_names] == NULL)
	goto end;

    /*
     * Remove the one from 'shortname', if it's the same as with 'noshortname'.
     */
    p = names[num_names];
    i = STRLEN(names[num_names]) - STRLEN(names[num_names - 1]);
    if (i > 0)
	p += i;		// file name has been expanded to full path
    if (STRCMP(names[num_names - 1], p) == 0)
	vim_free(names[num_names]);
    else
	++num_names;
# endif

end:
# ifndef MSWIN
    curbuf->b_shortname = shortname;
# endif

    return num_names;
}

/*
 * sync all memlines
 *
 * If 'check_file' is TRUE, check if original file exists and was not changed.
 * If 'check_char' is TRUE, stop syncing when character becomes available, but
 * always sync at least one block.
 */
    void
ml_sync_all(int check_file, int check_char)
{
    buf_T		*buf;
    stat_T		st;

    FOR_ALL_BUFFERS(buf)
    {
	if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
	    continue;			    // no file

	ml_flush_line(buf);		    // flush buffered line
					    // flush locked block
	(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH);
	if (bufIsChanged(buf) && check_file && mf_need_trans(buf->b_ml.ml_mfp)
						     && buf->b_ffname != NULL)
	{
	    /*
	     * If the original file does not exist anymore or has been changed
	     * call ml_preserve() to get rid of all negative numbered blocks.
	     */
	    if (mch_stat((char *)buf->b_ffname, &st) == -1
		    || st.st_mtime != buf->b_mtime_read
		    || st.st_size != buf->b_orig_size)
	    {
		ml_preserve(buf, FALSE);
		did_check_timestamps = FALSE;
		need_check_timestamps = TRUE;	// give message later
	    }
	}
	if (buf->b_ml.ml_mfp->mf_dirty)
	{
	    (void)mf_sync(buf->b_ml.ml_mfp, (check_char ? MFS_STOP : 0)
					| (bufIsChanged(buf) ? MFS_FLUSH : 0));
	    if (check_char && ui_char_avail())	// character available now
		break;
	}
    }
}

/*
 * sync one buffer, including negative blocks
 *
 * after this all the blocks are in the swap file
 *
 * Used for the :preserve command and when the original file has been
 * changed or deleted.
 *
 * when message is TRUE the success of preserving is reported
 */
    void
ml_preserve(buf_T *buf, int message)
{
    bhdr_T	*hp;
    linenr_T	lnum;
    memfile_T	*mfp = buf->b_ml.ml_mfp;
    int		status;
    int		got_int_save = got_int;

    if (mfp == NULL || mfp->mf_fname == NULL)
    {
	if (message)
	    emsg(_("E313: Cannot preserve, there is no swap file"));
	return;
    }

    // We only want to stop when interrupted here, not when interrupted
    // before.
    got_int = FALSE;

    ml_flush_line(buf);				    // flush buffered line
    (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); // flush locked block
    status = mf_sync(mfp, MFS_ALL | MFS_FLUSH);

    // stack is invalid after mf_sync(.., MFS_ALL)
    buf->b_ml.ml_stack_top = 0;

    /*
     * Some of the data blocks may have been changed from negative to
     * positive block number. In that case the pointer blocks need to be
     * updated.
     *
     * We don't know in which pointer block the references are, so we visit
     * all data blocks until there are no more translations to be done (or
     * we hit the end of the file, which can only happen in case a write fails,
     * e.g. when file system if full).
     * ml_find_line() does the work by translating the negative block numbers
     * when getting the first line of each data block.
     */
    if (mf_need_trans(mfp) && !got_int)
    {
	lnum = 1;
	while (mf_need_trans(mfp) && lnum <= buf->b_ml.ml_line_count)
	{
	    hp = ml_find_line(buf, lnum, ML_FIND);
	    if (hp == NULL)
	    {
		status = FAIL;
		goto theend;
	    }
	    CHECK(buf->b_ml.ml_locked_low != lnum, "low != lnum");
	    lnum = buf->b_ml.ml_locked_high + 1;
	}
	(void)ml_find_line(buf, (linenr_T)0, ML_FLUSH);	// flush locked block
	// sync the updated pointer blocks
	if (mf_sync(mfp, MFS_ALL | MFS_FLUSH) == FAIL)
	    status = FAIL;
	buf->b_ml.ml_stack_top = 0;	    // stack is invalid now
    }
theend:
    got_int |= got_int_save;

    if (message)
    {
	if (status == OK)
	    msg(_("File preserved"));
	else
	    emsg(_("E314: Preserve failed"));
    }
}

/*
 * NOTE: The pointer returned by the ml_get_*() functions only remains valid
 * until the next call!
 *  line1 = ml_get(1);
 *  line2 = ml_get(2);	// line1 is now invalid!
 * Make a copy of the line if necessary.
 */
/*
 * Return a pointer to a (read-only copy of a) line.
 *
 * On failure an error message is given and IObuff is returned (to avoid
 * having to check for error everywhere).
 */
    char_u  *
ml_get(linenr_T lnum)
{
    return ml_get_buf(curbuf, lnum, FALSE);
}

/*
 * Return pointer to position "pos".
 */
    char_u *
ml_get_pos(pos_T *pos)
{
    return (ml_get_buf(curbuf, pos->lnum, FALSE) + pos->col);
}

/*
 * Return pointer to cursor line.
 */
    char_u *
ml_get_curline(void)
{
    return ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE);
}

/*
 * Return pointer to cursor position.
 */
    char_u *
ml_get_cursor(void)
{
    return (ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE) +
							curwin->w_cursor.col);
}

/*
 * Return a pointer to a line in a specific buffer
 *
 * "will_change": if TRUE mark the buffer dirty (chars in the line will be
 * changed)
 */
    char_u  *
ml_get_buf(
    buf_T	*buf,
    linenr_T	lnum,
    int		will_change)		// line will be changed
{
    bhdr_T	*hp;
    DATA_BL	*dp;
    static int	recursive = 0;

    if (lnum > buf->b_ml.ml_line_count)	// invalid line number
    {
	if (recursive == 0)
	{
	    // Avoid giving this message for a recursive call, may happen when
	    // the GUI redraws part of the text.
	    ++recursive;
	    siemsg(_("E315: ml_get: invalid lnum: %ld"), lnum);
	    --recursive;
	}
errorret:
	STRCPY(IObuff, "???");
	buf->b_ml.ml_line_len = 4;
	return IObuff;
    }
    if (lnum <= 0)			// pretend line 0 is line 1
	lnum = 1;

    if (buf->b_ml.ml_mfp == NULL)	// there are no lines
    {
	buf->b_ml.ml_line_len = 1;
	return (char_u *)"";
    }

    /*
     * See if it is the same line as requested last time.
     * Otherwise may need to flush last used line.
     * Don't use the last used line when 'swapfile' is reset, need to load all
     * blocks.
     */
    if (buf->b_ml.ml_line_lnum != lnum || mf_dont_release)
    {
	unsigned    start, end;
	colnr_T	    len;
	int	    idx;

	ml_flush_line(buf);

	/*
	 * Find the data block containing the line.
	 * This also fills the stack with the blocks from the root to the data
	 * block and releases any locked block.
	 */
	if ((hp = ml_find_line(buf, lnum, ML_FIND)) == NULL)
	{
	    if (recursive == 0)
	    {
		// Avoid giving this message for a recursive call, may happen
		// when the GUI redraws part of the text.
		++recursive;
		get_trans_bufname(buf);
		shorten_dir(NameBuff);
		siemsg(_("E316: ml_get: cannot find line %ld in buffer %d %s"),
						  lnum, buf->b_fnum, NameBuff);
		--recursive;
	    }
	    goto errorret;
	}

	dp = (DATA_BL *)(hp->bh_data);

	idx = lnum - buf->b_ml.ml_locked_low;
	start = ((dp->db_index[idx]) & DB_INDEX_MASK);
	// The text ends where the previous line starts.  The first line ends
	// at the end of the block.
	if (idx == 0)
	    end = dp->db_txt_end;
	else
	    end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
	len = end - start;

	buf->b_ml.ml_line_ptr = (char_u *)dp + start;
	buf->b_ml.ml_line_len = len;
	buf->b_ml.ml_line_lnum = lnum;
	buf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
    }
    if (will_change)
	buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);

    return buf->b_ml.ml_line_ptr;
}

/*
 * Check if a line that was just obtained by a call to ml_get
 * is in allocated memory.
 */
    int
ml_line_alloced(void)
{
    return (curbuf->b_ml.ml_flags & ML_LINE_DIRTY);
}

#ifdef FEAT_PROP_POPUP
    static void
add_text_props_for_append(
	    buf_T	*buf,
	    linenr_T	lnum,
	    char_u	**line,
	    int		*len,
	    char_u	**tofree)
{
    int		round;
    int		new_prop_count = 0;
    int		count;
    int		n;
    char_u	*props;
    int		new_len = 0;  // init for gcc
    char_u	*new_line;
    textprop_T	prop;

    // Make two rounds:
    // 1. calculate the extra space needed
    // 2. allocate the space and fill it
    for (round = 1; round <= 2; ++round)
    {
	if (round == 2)
	{
	    if (new_prop_count == 0)
		return;  // nothing to do
	    new_len = *len + new_prop_count * sizeof(textprop_T);
	    new_line = alloc(new_len);
	    if (new_line == NULL)
		return;
	    mch_memmove(new_line, *line, *len);
	    new_prop_count = 0;
	}

	// Get the line above to find any props that continue in the next
	// line.
	count = get_text_props(buf, lnum, &props, FALSE);
	for (n = 0; n < count; ++n)
	{
	    mch_memmove(&prop, props + n * sizeof(textprop_T), sizeof(textprop_T));
	    if (prop.tp_flags & TP_FLAG_CONT_NEXT)
	    {
		if (round == 2)
		{
		    prop.tp_flags |= TP_FLAG_CONT_PREV;
		    prop.tp_col = 1;
		    prop.tp_len = *len;
		    mch_memmove(new_line + *len + new_prop_count * sizeof(textprop_T), &prop, sizeof(textprop_T));
		}
		++new_prop_count;
	    }
	}
    }
    *line = new_line;
    *tofree = new_line;
    *len = new_len;
}
#endif

    static int
ml_append_int(
    buf_T	*buf,
    linenr_T	lnum,		// append after this line (can be 0)
    char_u	*line_arg,	// text of the new line
    colnr_T	len_arg,	// length of line, including NUL, or 0
    int		newfile,	// flag, see above
    int		mark)		// mark the new line
{
    char_u	*line = line_arg;
    colnr_T	len = len_arg;
    int		i;
    int		line_count;	// number of indexes in current block
    int		offset;
    int		from, to;
    int		space_needed;	// space needed for new line
    int		page_size;
    int		page_count;
    int		db_idx;		// index for lnum in data block
    bhdr_T	*hp;
    memfile_T	*mfp;
    DATA_BL	*dp;
    PTR_BL	*pp;
    infoptr_T	*ip;
#ifdef FEAT_PROP_POPUP
    char_u	*tofree = NULL;
#endif
    int		ret = FAIL;

    if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL)
	return FAIL;  // lnum out of range

    if (lowest_marked && lowest_marked > lnum)
	lowest_marked = lnum + 1;

    if (len == 0)
	len = (colnr_T)STRLEN(line) + 1;	// space needed for the text

#ifdef FEAT_PROP_POPUP
    if (curbuf->b_has_textprop && lnum > 0)
	// Add text properties that continue from the previous line.
	add_text_props_for_append(buf, lnum, &line, &len, &tofree);
#endif

    space_needed = len + INDEX_SIZE;	// space needed for text + index

    mfp = buf->b_ml.ml_mfp;
    page_size = mfp->mf_page_size;

/*
 * find the data block containing the previous line
 * This also fills the stack with the blocks from the root to the data block
 * This also releases any locked block.
 */
    if ((hp = ml_find_line(buf, lnum == 0 ? (linenr_T)1 : lnum,
							  ML_INSERT)) == NULL)
	goto theend;

    buf->b_ml.ml_flags &= ~ML_EMPTY;

    if (lnum == 0)		// got line one instead, correct db_idx
	db_idx = -1;		// careful, it is negative!
    else
	db_idx = lnum - buf->b_ml.ml_locked_low;
		// get line count before the insertion
    line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;

    dp = (DATA_BL *)(hp->bh_data);

/*
 * If
 * - there is not enough room in the current block
 * - appending to the last line in the block
 * - not appending to the last line in the file
 * insert in front of the next block.
 */
    if ((int)dp->db_free < space_needed && db_idx == line_count - 1
					    && lnum < buf->b_ml.ml_line_count)
    {
	/*
	 * Now that the line is not going to be inserted in the block that we
	 * expected, the line count has to be adjusted in the pointer blocks
	 * by using ml_locked_lineadd.
	 */
	--(buf->b_ml.ml_locked_lineadd);
	--(buf->b_ml.ml_locked_high);
	if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL)
	    goto theend;

	db_idx = -1;		    // careful, it is negative!
		    // get line count before the insertion
	line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
	CHECK(buf->b_ml.ml_locked_low != lnum + 1, "locked_low != lnum + 1");

	dp = (DATA_BL *)(hp->bh_data);
    }

    ++buf->b_ml.ml_line_count;

    if ((int)dp->db_free >= space_needed)	// enough room in data block
    {
	/*
	 * Insert the new line in an existing data block, or in the data block
	 * allocated above.
	 */
	dp->db_txt_start -= len;
	dp->db_free -= space_needed;
	++(dp->db_line_count);

	/*
	 * move the text of the lines that follow to the front
	 * adjust the indexes of the lines that follow
	 */
	if (line_count > db_idx + 1)	    // if there are following lines
	{
	    /*
	     * Offset is the start of the previous line.
	     * This will become the character just after the new line.
	     */
	    if (db_idx < 0)
		offset = dp->db_txt_end;
	    else
		offset = ((dp->db_index[db_idx]) & DB_INDEX_MASK);
	    mch_memmove((char *)dp + dp->db_txt_start,
					  (char *)dp + dp->db_txt_start + len,
				 (size_t)(offset - (dp->db_txt_start + len)));
	    for (i = line_count - 1; i > db_idx; --i)
		dp->db_index[i + 1] = dp->db_index[i] - len;
	    dp->db_index[db_idx + 1] = offset - len;
	}
	else
	    // add line at the end (which is the start of the text)
	    dp->db_index[db_idx + 1] = dp->db_txt_start;

	/*
	 * copy the text into the block
	 */
	mch_memmove((char *)dp + dp->db_index[db_idx + 1], line, (size_t)len);
	if (mark)
	    dp->db_index[db_idx + 1] |= DB_MARKED;

	/*
	 * Mark the block dirty.
	 */
	buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
	if (!newfile)
	    buf->b_ml.ml_flags |= ML_LOCKED_POS;
    }
    else	    // not enough space in data block
    {
	long	    line_count_left, line_count_right;
	int	    page_count_left, page_count_right;
	bhdr_T	    *hp_left;
	bhdr_T	    *hp_right;
	bhdr_T	    *hp_new;
	int	    lines_moved;
	int	    data_moved = 0;	    // init to shut up gcc
	int	    total_moved = 0;	    // init to shut up gcc
	DATA_BL	    *dp_right, *dp_left;
	int	    stack_idx;
	int	    in_left;
	int	    lineadd;
	blocknr_T   bnum_left, bnum_right;
	linenr_T    lnum_left, lnum_right;
	int	    pb_idx;
	PTR_BL	    *pp_new;

	/*
	 * There is not enough room, we have to create a new data block and
	 * copy some lines into it.
	 * Then we have to insert an entry in the pointer block.
	 * If this pointer block also is full, we go up another block, and so
	 * on, up to the root if necessary.
	 * The line counts in the pointer blocks have already been adjusted by
	 * ml_find_line().
	 *
	 * We are going to allocate a new data block. Depending on the
	 * situation it will be put to the left or right of the existing
	 * block.  If possible we put the new line in the left block and move
	 * the lines after it to the right block. Otherwise the new line is
	 * also put in the right block. This method is more efficient when
	 * inserting a lot of lines at one place.
	 */
	if (db_idx < 0)		// left block is new, right block is existing
	{
	    lines_moved = 0;
	    in_left = TRUE;
	    // space_needed does not change
	}
	else			// left block is existing, right block is new
	{
	    lines_moved = line_count - db_idx - 1;
	    if (lines_moved == 0)
		in_left = FALSE;	// put new line in right block
					// space_needed does not change
	    else
	    {
		data_moved = ((dp->db_index[db_idx]) & DB_INDEX_MASK) -
							    dp->db_txt_start;
		total_moved = data_moved + lines_moved * INDEX_SIZE;
		if ((int)dp->db_free + total_moved >= space_needed)
		{
		    in_left = TRUE;	// put new line in left block
		    space_needed = total_moved;
		}
		else
		{
		    in_left = FALSE;	    // put new line in right block
		    space_needed += total_moved;
		}
	    }
	}

	page_count = ((space_needed + HEADER_SIZE) + page_size - 1) / page_size;
	if ((hp_new = ml_new_data(mfp, newfile, page_count)) == NULL)
	{
			// correct line counts in pointer blocks
	    --(buf->b_ml.ml_locked_lineadd);
	    --(buf->b_ml.ml_locked_high);
	    goto theend;
	}
	if (db_idx < 0)		// left block is new
	{
	    hp_left = hp_new;
	    hp_right = hp;
	    line_count_left = 0;
	    line_count_right = line_count;
	}
	else			// right block is new
	{
	    hp_left = hp;
	    hp_right = hp_new;
	    line_count_left = line_count;
	    line_count_right = 0;
	}
	dp_right = (DATA_BL *)(hp_right->bh_data);
	dp_left = (DATA_BL *)(hp_left->bh_data);
	bnum_left = hp_left->bh_bnum;
	bnum_right = hp_right->bh_bnum;
	page_count_left = hp_left->bh_page_count;
	page_count_right = hp_right->bh_page_count;

	/*
	 * May move the new line into the right/new block.
	 */
	if (!in_left)
	{
	    dp_right->db_txt_start -= len;
	    dp_right->db_free -= len + INDEX_SIZE;
	    dp_right->db_index[0] = dp_right->db_txt_start;
	    if (mark)
		dp_right->db_index[0] |= DB_MARKED;

	    mch_memmove((char *)dp_right + dp_right->db_txt_start,
							   line, (size_t)len);
	    ++line_count_right;
	}
	/*
	 * may move lines from the left/old block to the right/new one.
	 */
	if (lines_moved)
	{
	    /*
	     */
	    dp_right->db_txt_start -= data_moved;
	    dp_right->db_free -= total_moved;
	    mch_memmove((char *)dp_right + dp_right->db_txt_start,
			(char *)dp_left + dp_left->db_txt_start,
			(size_t)data_moved);
	    offset = dp_right->db_txt_start - dp_left->db_txt_start;
	    dp_left->db_txt_start += data_moved;
	    dp_left->db_free += total_moved;

	    /*
	     * update indexes in the new block
	     */
	    for (to = line_count_right, from = db_idx + 1;
					 from < line_count_left; ++from, ++to)
		dp_right->db_index[to] = dp->db_index[from] + offset;
	    line_count_right += lines_moved;
	    line_count_left -= lines_moved;
	}

	/*
	 * May move the new line into the left (old or new) block.
	 */
	if (in_left)
	{
	    dp_left->db_txt_start -= len;
	    dp_left->db_free -= len + INDEX_SIZE;
	    dp_left->db_index[line_count_left] = dp_left->db_txt_start;
	    if (mark)
		dp_left->db_index[line_count_left] |= DB_MARKED;
	    mch_memmove((char *)dp_left + dp_left->db_txt_start,
							   line, (size_t)len);
	    ++line_count_left;
	}

	if (db_idx < 0)		// left block is new
	{
	    lnum_left = lnum + 1;
	    lnum_right = 0;
	}
	else			// right block is new
	{
	    lnum_left = 0;
	    if (in_left)
		lnum_right = lnum + 2;
	    else
		lnum_right = lnum + 1;
	}
	dp_left->db_line_count = line_count_left;
	dp_right->db_line_count = line_count_right;

	/*
	 * release the two data blocks
	 * The new one (hp_new) already has a correct blocknumber.
	 * The old one (hp, in ml_locked) gets a positive blocknumber if
	 * we changed it and we are not editing a new file.
	 */
	if (lines_moved || in_left)
	    buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
	if (!newfile && db_idx >= 0 && in_left)
	    buf->b_ml.ml_flags |= ML_LOCKED_POS;
	mf_put(mfp, hp_new, TRUE, FALSE);

	/*
	 * flush the old data block
	 * set ml_locked_lineadd to 0, because the updating of the
	 * pointer blocks is done below
	 */
	lineadd = buf->b_ml.ml_locked_lineadd;
	buf->b_ml.ml_locked_lineadd = 0;
	ml_find_line(buf, (linenr_T)0, ML_FLUSH);   // flush data block

	/*
	 * update pointer blocks for the new data block
	 */
	for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0;
								  --stack_idx)
	{
	    ip = &(buf->b_ml.ml_stack[stack_idx]);
	    pb_idx = ip->ip_index;
	    if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
		goto theend;
	    pp = (PTR_BL *)(hp->bh_data);   // must be pointer block
	    if (pp->pb_id != PTR_ID)
	    {
		iemsg(_("E317: pointer block id wrong 3"));
		mf_put(mfp, hp, FALSE, FALSE);
		goto theend;
	    }
	    /*
	     * TODO: If the pointer block is full and we are adding at the end
	     * try to insert in front of the next block
	     */
	    // block not full, add one entry
	    if (pp->pb_count < pp->pb_count_max)
	    {
		if (pb_idx + 1 < (int)pp->pb_count)
		    mch_memmove(&pp->pb_pointer[pb_idx + 2],
				&pp->pb_pointer[pb_idx + 1],
			(size_t)(pp->pb_count - pb_idx - 1) * sizeof(PTR_EN));
		++pp->pb_count;
		pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
		pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
		pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
		pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
		pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
		pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;

		if (lnum_left != 0)
		    pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
		if (lnum_right != 0)
		    pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;

		mf_put(mfp, hp, TRUE, FALSE);
		buf->b_ml.ml_stack_top = stack_idx + 1;	    // truncate stack

		if (lineadd)
		{
		    --(buf->b_ml.ml_stack_top);
		    // fix line count for rest of blocks in the stack
		    ml_lineadd(buf, lineadd);
							// fix stack itself
		    buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
								      lineadd;
		    ++(buf->b_ml.ml_stack_top);
		}

		/*
		 * We are finished, break the loop here.
		 */
		break;
	    }
	    else			// pointer block full
	    {
		/*
		 * split the pointer block
		 * allocate a new pointer block
		 * move some of the pointer into the new block
		 * prepare for updating the parent block
		 */
		for (;;)	// do this twice when splitting block 1
		{
		    hp_new = ml_new_ptr(mfp);
		    if (hp_new == NULL)	    // TODO: try to fix tree
			goto theend;
		    pp_new = (PTR_BL *)(hp_new->bh_data);

		    if (hp->bh_bnum != 1)
			break;

		    /*
		     * if block 1 becomes full the tree is given an extra level
		     * The pointers from block 1 are moved into the new block.
		     * block 1 is updated to point to the new block
		     * then continue to split the new block
		     */
		    mch_memmove(pp_new, pp, (size_t)page_size);
		    pp->pb_count = 1;
		    pp->pb_pointer[0].pe_bnum = hp_new->bh_bnum;
		    pp->pb_pointer[0].pe_line_count = buf->b_ml.ml_line_count;
		    pp->pb_pointer[0].pe_old_lnum = 1;
		    pp->pb_pointer[0].pe_page_count = 1;
		    mf_put(mfp, hp, TRUE, FALSE);   // release block 1
		    hp = hp_new;		// new block is to be split
		    pp = pp_new;
		    CHECK(stack_idx != 0, _("stack_idx should be 0"));
		    ip->ip_index = 0;
		    ++stack_idx;	// do block 1 again later
		}
		/*
		 * move the pointers after the current one to the new block
		 * If there are none, the new entry will be in the new block.
		 */
		total_moved = pp->pb_count - pb_idx - 1;
		if (total_moved)
		{
		    mch_memmove(&pp_new->pb_pointer[0],
				&pp->pb_pointer[pb_idx + 1],
				(size_t)(total_moved) * sizeof(PTR_EN));
		    pp_new->pb_count = total_moved;
		    pp->pb_count -= total_moved - 1;
		    pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
		    pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
		    pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
		    if (lnum_right)
			pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
		}
		else
		{
		    pp_new->pb_count = 1;
		    pp_new->pb_pointer[0].pe_bnum = bnum_right;
		    pp_new->pb_pointer[0].pe_line_count = line_count_right;
		    pp_new->pb_pointer[0].pe_page_count = page_count_right;
		    pp_new->pb_pointer[0].pe_old_lnum = lnum_right;
		}
		pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
		pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
		pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
		if (lnum_left)
		    pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
		lnum_left = 0;
		lnum_right = 0;

		/*
		 * recompute line counts
		 */
		line_count_right = 0;
		for (i = 0; i < (int)pp_new->pb_count; ++i)
		    line_count_right += pp_new->pb_pointer[i].pe_line_count;
		line_count_left = 0;
		for (i = 0; i < (int)pp->pb_count; ++i)
		    line_count_left += pp->pb_pointer[i].pe_line_count;

		bnum_left = hp->bh_bnum;
		bnum_right = hp_new->bh_bnum;
		page_count_left = 1;
		page_count_right = 1;
		mf_put(mfp, hp, TRUE, FALSE);
		mf_put(mfp, hp_new, TRUE, FALSE);
	    }
	}

	/*
	 * Safety check: fallen out of for loop?
	 */
	if (stack_idx < 0)
	{
	    iemsg(_("E318: Updated too many blocks?"));
	    buf->b_ml.ml_stack_top = 0;	// invalidate stack
	}
    }

#ifdef FEAT_BYTEOFF
    // The line was inserted below 'lnum'
    ml_updatechunk(buf, lnum + 1, (long)len, ML_CHNK_ADDLINE);
#endif
#ifdef FEAT_NETBEANS_INTG
    if (netbeans_active())
    {
	if (STRLEN(line) > 0)
	    netbeans_inserted(buf, lnum+1, (colnr_T)0, line, (int)STRLEN(line));
	netbeans_inserted(buf, lnum+1, (colnr_T)STRLEN(line),
							   (char_u *)"\n", 1);
    }
#endif
#ifdef FEAT_JOB_CHANNEL
    if (buf->b_write_to_channel)
	channel_write_new_lines(buf);
#endif
    ret = OK;

theend:
#ifdef FEAT_PROP_POPUP
    vim_free(tofree);
#endif
    return ret;
}

/*
 * Flush any pending change and call ml_append_int()
 */
    static int
ml_append_flush(
    buf_T	*buf,
    linenr_T	lnum,		// append after this line (can be 0)
    char_u	*line,		// text of the new line
    colnr_T	len,		// length of line, including NUL, or 0
    int		newfile)	// flag, see above
{
    if (lnum > buf->b_ml.ml_line_count)
	return FAIL;  // lnum out of range

    if (buf->b_ml.ml_line_lnum != 0)
	// This may also invoke ml_append_int().
	ml_flush_line(buf);

#ifdef FEAT_EVAL
    // When inserting above recorded changes: flush the changes before changing
    // the text.  Then flush the cached line, it may become invalid.
    may_invoke_listeners(buf, lnum + 1, lnum + 1, 1);
    if (buf->b_ml.ml_line_lnum != 0)
	ml_flush_line(buf);
#endif

    return ml_append_int(buf, lnum, line, len, newfile, FALSE);
}

/*
 * Append a line after lnum (may be 0 to insert a line in front of the file).
 * "line" does not need to be allocated, but can't be another line in a
 * buffer, unlocking may make it invalid.
 *
 *   newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum
 *		will be set for recovery
 * Check: The caller of this function should probably also call
 * appended_lines().
 *
 * return FAIL for failure, OK otherwise
 */
    int
ml_append(
    linenr_T	lnum,		// append after this line (can be 0)
    char_u	*line,		// text of the new line
    colnr_T	len,		// length of new line, including NUL, or 0
    int		newfile)	// flag, see above
{
    // When starting up, we might still need to create the memfile
    if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
	return FAIL;
    return ml_append_flush(curbuf, lnum, line, len, newfile);
}

#if defined(FEAT_SPELL) || defined(FEAT_QUICKFIX) || defined(PROTO)
/*
 * Like ml_append() but for an arbitrary buffer.  The buffer must already have
 * a memline.
 */
    int
ml_append_buf(
    buf_T	*buf,
    linenr_T	lnum,		// append after this line (can be 0)
    char_u	*line,		// text of the new line
    colnr_T	len,		// length of new line, including NUL, or 0
    int		newfile)	// flag, see above
{
    if (buf->b_ml.ml_mfp == NULL)
	return FAIL;
    return ml_append_flush(buf, lnum, line, len, newfile);
}
#endif

/*
 * Replace line lnum, with buffering, in current buffer.
 *
 * If "copy" is TRUE, make a copy of the line, otherwise the line has been
 * copied to allocated memory already.
 *
 * Check: The caller of this function should probably also call
 * changed_lines(), unless update_screen(NOT_VALID) is used.
 *
 * return FAIL for failure, OK otherwise
 */
    int
ml_replace(linenr_T lnum, char_u *line, int copy)
{
    colnr_T len = -1;

    if (line != NULL)
	len = (colnr_T)STRLEN(line);
    return ml_replace_len(lnum, line, len, FALSE, copy);
}

/*
 * Replace a line for the current buffer.  Like ml_replace() with:
 * "len_arg" is the length of the text, excluding NUL.
 * If "has_props" is TRUE then "line_arg" includes the text properties and
 * "len_arg" includes the NUL of the text.
 */
    int
ml_replace_len(
	linenr_T    lnum,
	char_u	    *line_arg,
	colnr_T	    len_arg,
	int	    has_props,
	int	    copy)
{
    char_u *line = line_arg;
    colnr_T len = len_arg;

    if (line == NULL)		// just checking...
	return FAIL;

    // When starting up, we might still need to create the memfile
    if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
	return FAIL;

    if (!has_props)
	++len;  // include the NUL after the text
    if (copy)
    {
	// copy the line to allocated memory
#ifdef FEAT_PROP_POPUP
	if (has_props)
	    line = vim_memsave(line, len);
	else
#endif
	    line = vim_strnsave(line, len - 1);
	if (line == NULL)
	    return FAIL;
    }

#ifdef FEAT_NETBEANS_INTG
    if (netbeans_active())
    {
	netbeans_removed(curbuf, lnum, 0, (long)STRLEN(ml_get(lnum)));
	netbeans_inserted(curbuf, lnum, 0, line, (int)STRLEN(line));
    }
#endif
    if (curbuf->b_ml.ml_line_lnum != lnum)
    {
	// another line is buffered, flush it
	ml_flush_line(curbuf);
	curbuf->b_ml.ml_flags &= ~ML_LINE_DIRTY;

#ifdef FEAT_PROP_POPUP
	if (curbuf->b_has_textprop && !has_props)
	    // Need to fetch the old line to copy over any text properties.
	    ml_get_buf(curbuf, lnum, TRUE);
#endif
    }

#ifdef FEAT_PROP_POPUP
    if (curbuf->b_has_textprop && !has_props)
    {
	size_t	oldtextlen = STRLEN(curbuf->b_ml.ml_line_ptr) + 1;

	if (oldtextlen < (size_t)curbuf->b_ml.ml_line_len)
	{
	    char_u *newline;
	    size_t textproplen = curbuf->b_ml.ml_line_len - oldtextlen;

	    // Need to copy over text properties, stored after the text.
	    newline = alloc(len + (int)textproplen);
	    if (newline != NULL)
	    {
		mch_memmove(newline, line, len);
		mch_memmove(newline + len, curbuf->b_ml.ml_line_ptr
						    + oldtextlen, textproplen);
		vim_free(line);
		line = newline;
		len += (colnr_T)textproplen;
	    }
	}
    }
#endif

    if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY)	// same line allocated
	vim_free(curbuf->b_ml.ml_line_ptr);	// free it

    curbuf->b_ml.ml_line_ptr = line;
    curbuf->b_ml.ml_line_len = len;
    curbuf->b_ml.ml_line_lnum = lnum;
    curbuf->b_ml.ml_flags = (curbuf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY;

    return OK;
}

#ifdef FEAT_PROP_POPUP
/*
 * Adjust text properties in line "lnum" for a deleted line.
 * When "above" is true this is the line above the deleted line.
 * "del_props" are the properties of the deleted line.
 */
    static void
adjust_text_props_for_delete(
	buf_T	    *buf,
	linenr_T    lnum,
	char_u	    *del_props,
	int	    del_props_len,
	int	    above)
{
    int		did_get_line = FALSE;
    int		done_del;
    int		done_this;
    textprop_T	prop_del;
    textprop_T	prop_this;
    bhdr_T	*hp;
    DATA_BL	*dp;
    int		idx;
    int		line_start;
    long	line_size;
    int		this_props_len;
    char_u	*text;
    size_t	textlen;
    int		found;

    for (done_del = 0; done_del < del_props_len; done_del += sizeof(textprop_T))
    {
	mch_memmove(&prop_del, del_props + done_del, sizeof(textprop_T));
	if ((above && (prop_del.tp_flags & TP_FLAG_CONT_PREV)
		    && !(prop_del.tp_flags & TP_FLAG_CONT_NEXT))
		|| (!above && (prop_del.tp_flags & TP_FLAG_CONT_NEXT)
		    && !(prop_del.tp_flags & TP_FLAG_CONT_PREV)))
	{
	    if (!did_get_line)
	    {
		did_get_line = TRUE;
		if ((hp = ml_find_line(buf, lnum, ML_FIND)) == NULL)
		    return;

		dp = (DATA_BL *)(hp->bh_data);
		idx = lnum - buf->b_ml.ml_locked_low;
		line_start = ((dp->db_index[idx]) & DB_INDEX_MASK);
		if (idx == 0)		// first line in block, text at the end
		    line_size = dp->db_txt_end - line_start;
		else
		    line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start;
		text = (char_u *)dp + line_start;
		textlen = STRLEN(text) + 1;
		if ((long)textlen >= line_size)
		{
		    if (above)
			internal_error("no text property above deleted line");
		    else
			internal_error("no text property below deleted line");
		    return;
		}
		this_props_len = line_size - (int)textlen;
	    }

	    found = FALSE;
	    for (done_this = 0; done_this < this_props_len; done_this += sizeof(textprop_T))
	    {
		mch_memmove(&prop_this, text + textlen + done_del, sizeof(textprop_T));
		if (prop_del.tp_id == prop_this.tp_id
			&& prop_del.tp_type == prop_this.tp_type)
		{
		    int flag = above ? TP_FLAG_CONT_NEXT : TP_FLAG_CONT_PREV;

		    found = TRUE;
		    if (prop_this.tp_flags & flag)
		    {
			prop_this.tp_flags &= ~flag;
			mch_memmove(text + textlen + done_del, &prop_this, sizeof(textprop_T));
		    }
		    else if (above)
			internal_error("text property above deleted line does not continue");
		    else
			internal_error("text property below deleted line does not continue");
		}
	    }
	    if (!found)
	    {
		if (above)
		    internal_error("text property above deleted line not found");
		else
		    internal_error("text property below deleted line not found");
	    }

	    buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
	}
    }
}
#endif

/*
 * Delete line "lnum" in the current buffer.
 * When "message" is TRUE may give a "No lines in buffer" message.
 *
 * Check: The caller of this function should probably also call
 * deleted_lines() after this.
 *
 * return FAIL for failure, OK otherwise
 */
    int
ml_delete(linenr_T lnum, int message)
{
    ml_flush_line(curbuf);
    if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
	return FAIL;

#ifdef FEAT_EVAL
    // When inserting above recorded changes: flush the changes before changing
    // the text.
    may_invoke_listeners(curbuf, lnum, lnum + 1, -1);
#endif

    return ml_delete_int(curbuf, lnum, message);
}

    static int
ml_delete_int(buf_T *buf, linenr_T lnum, int message)
{
    bhdr_T	*hp;
    memfile_T	*mfp;
    DATA_BL	*dp;
    PTR_BL	*pp;
    infoptr_T	*ip;
    int		count;	    // number of entries in block
    int		idx;
    int		stack_idx;
    int		text_start;
    int		line_start;
    long	line_size;
    int		i;
    int		ret = FAIL;
#ifdef FEAT_PROP_POPUP
    char_u	*textprop_save = NULL;
    int		textprop_save_len;
#endif

    if (lowest_marked && lowest_marked > lnum)
	lowest_marked--;

/*
 * If the file becomes empty the last line is replaced by an empty line.
 */
    if (buf->b_ml.ml_line_count == 1)	    // file becomes empty
    {
	if (message
#ifdef FEAT_NETBEANS_INTG
		&& !netbeansSuppressNoLines
#endif
	   )
	    set_keep_msg((char_u *)_(no_lines_msg), 0);

	// FEAT_BYTEOFF already handled in there, don't worry 'bout it below
	i = ml_replace((linenr_T)1, (char_u *)"", TRUE);
	buf->b_ml.ml_flags |= ML_EMPTY;

	return i;
    }

/*
 * Find the data block containing the line.
 * This also fills the stack with the blocks from the root to the data block.
 * This also releases any locked block..
 */
    mfp = buf->b_ml.ml_mfp;
    if (mfp == NULL)
	return FAIL;

    if ((hp = ml_find_line(buf, lnum, ML_DELETE)) == NULL)
	return FAIL;

    dp = (DATA_BL *)(hp->bh_data);
    // compute line count before the delete
    count = (long)(buf->b_ml.ml_locked_high)
					- (long)(buf->b_ml.ml_locked_low) + 2;
    idx = lnum - buf->b_ml.ml_locked_low;

    --buf->b_ml.ml_line_count;

    line_start = ((dp->db_index[idx]) & DB_INDEX_MASK);
    if (idx == 0)		// first line in block, text at the end
	line_size = dp->db_txt_end - line_start;
    else
	line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start;

#ifdef FEAT_NETBEANS_INTG
    if (netbeans_active())
	netbeans_removed(buf, lnum, 0, (long)line_size);
#endif
#ifdef FEAT_PROP_POPUP
    // If there are text properties, make a copy, so that we can update
    // properties in preceding and following lines.
    if (buf->b_has_textprop)
    {
	size_t	textlen = STRLEN((char_u *)dp + line_start) + 1;

	if ((long)textlen < line_size)
	{
	    textprop_save_len = line_size - (int)textlen;
	    textprop_save = vim_memsave((char_u *)dp + line_start + textlen,
							  textprop_save_len);
	}
    }
#endif

/*
 * special case: If there is only one line in the data block it becomes empty.
 * Then we have to remove the entry, pointing to this data block, from the
 * pointer block. If this pointer block also becomes empty, we go up another
 * block, and so on, up to the root if necessary.
 * The line counts in the pointer blocks have already been adjusted by
 * ml_find_line().
 */
    if (count == 1)
    {
	mf_free(mfp, hp);	// free the data block
	buf->b_ml.ml_locked = NULL;

	for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0;
								  --stack_idx)
	{
	    buf->b_ml.ml_stack_top = 0;	    // stack is invalid when failing
	    ip = &(buf->b_ml.ml_stack[stack_idx]);
	    idx = ip->ip_index;
	    if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
		goto theend;
	    pp = (PTR_BL *)(hp->bh_data);   // must be pointer block
	    if (pp->pb_id != PTR_ID)
	    {
		iemsg(_("E317: pointer block id wrong 4"));
		mf_put(mfp, hp, FALSE, FALSE);
		goto theend;
	    }
	    count = --(pp->pb_count);
	    if (count == 0)	    // the pointer block becomes empty!
		mf_free(mfp, hp);
	    else
	    {
		if (count != idx)	// move entries after the deleted one
		    mch_memmove(&pp->pb_pointer[idx], &pp->pb_pointer[idx + 1],
				      (size_t)(count - idx) * sizeof(PTR_EN));
		mf_put(mfp, hp, TRUE, FALSE);

		buf->b_ml.ml_stack_top = stack_idx;	// truncate stack
		// fix line count for rest of blocks in the stack
		if (buf->b_ml.ml_locked_lineadd != 0)
		{
		    ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
		    buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
						  buf->b_ml.ml_locked_lineadd;
		}
		++(buf->b_ml.ml_stack_top);

		break;
	    }
	}
	CHECK(stack_idx < 0, _("deleted block 1?"));
    }
    else
    {
	/*
	 * delete the text by moving the next lines forwards
	 */
	text_start = dp->db_txt_start;
	mch_memmove((char *)dp + text_start + line_size,
		  (char *)dp + text_start, (size_t)(line_start - text_start));

	/*
	 * delete the index by moving the next indexes backwards
	 * Adjust the indexes for the text movement.
	 */
	for (i = idx; i < count - 1; ++i)
	    dp->db_index[i] = dp->db_index[i + 1] + line_size;

	dp->db_free += line_size + INDEX_SIZE;
	dp->db_txt_start += line_size;
	--(dp->db_line_count);

	/*
	 * mark the block dirty and make sure it is in the file (for recovery)
	 */
	buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
    }

#ifdef FEAT_BYTEOFF
    ml_updatechunk(buf, lnum, line_size, ML_CHNK_DELLINE);
#endif
    ret = OK;

theend:
#ifdef FEAT_PROP_POPUP
    if (textprop_save != NULL)
    {
	// Adjust text properties in the line above and below.
	if (lnum > 1)
	    adjust_text_props_for_delete(buf, lnum - 1, textprop_save, textprop_save_len, TRUE);
	if (lnum <= buf->b_ml.ml_line_count)
	    adjust_text_props_for_delete(buf, lnum, textprop_save, textprop_save_len, FALSE);
    }
    vim_free(textprop_save);
#endif
    return ret;
}

/*
 * set the DB_MARKED flag for line 'lnum'
 */
    void
ml_setmarked(linenr_T lnum)
{
    bhdr_T    *hp;
    DATA_BL *dp;
				    // invalid line number
    if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count
					       || curbuf->b_ml.ml_mfp == NULL)
	return;			    // give error message?

    if (lowest_marked == 0 || lowest_marked > lnum)
	lowest_marked = lnum;

    /*
     * find the data block containing the line
     * This also fills the stack with the blocks from the root to the data block
     * This also releases any locked block.
     */
    if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
	return;		    // give error message?

    dp = (DATA_BL *)(hp->bh_data);
    dp->db_index[lnum - curbuf->b_ml.ml_locked_low] |= DB_MARKED;
    curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
}

/*
 * find the first line with its DB_MARKED flag set
 */
    linenr_T
ml_firstmarked(void)
{
    bhdr_T	*hp;
    DATA_BL	*dp;
    linenr_T	lnum;
    int		i;

    if (curbuf->b_ml.ml_mfp == NULL)
	return (linenr_T) 0;

    /*
     * The search starts with lowest_marked line. This is the last line where
     * a mark was found, adjusted by inserting/deleting lines.
     */
    for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; )
    {
	/*
	 * Find the data block containing the line.
	 * This also fills the stack with the blocks from the root to the data
	 * block This also releases any locked block.
	 */
	if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
	    return (linenr_T)0;		    // give error message?

	dp = (DATA_BL *)(hp->bh_data);

	for (i = lnum - curbuf->b_ml.ml_locked_low;
			    lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
	    if ((dp->db_index[i]) & DB_MARKED)
	    {
		(dp->db_index[i]) &= DB_INDEX_MASK;
		curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
		lowest_marked = lnum + 1;
		return lnum;
	    }
    }

    return (linenr_T) 0;
}

/*
 * clear all DB_MARKED flags
 */
    void
ml_clearmarked(void)
{
    bhdr_T	*hp;
    DATA_BL	*dp;
    linenr_T	lnum;
    int		i;

    if (curbuf->b_ml.ml_mfp == NULL)	    // nothing to do
	return;

    /*
     * The search starts with line lowest_marked.
     */
    for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; )
    {
	/*
	 * Find the data block containing the line.
	 * This also fills the stack with the blocks from the root to the data
	 * block and releases any locked block.
	 */
	if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
	    return;		// give error message?

	dp = (DATA_BL *)(hp->bh_data);

	for (i = lnum - curbuf->b_ml.ml_locked_low;
			    lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
	    if ((dp->db_index[i]) & DB_MARKED)
	    {
		(dp->db_index[i]) &= DB_INDEX_MASK;
		curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
	    }
    }

    lowest_marked = 0;
    return;
}

/*
 * flush ml_line if necessary
 */
    static void
ml_flush_line(buf_T *buf)
{
    bhdr_T	*hp;
    DATA_BL	*dp;
    linenr_T	lnum;
    char_u	*new_line;
    char_u	*old_line;
    colnr_T	new_len;
    int		old_len;
    int		extra;
    int		idx;
    int		start;
    int		count;
    int		i;
    static int  entered = FALSE;

    if (buf->b_ml.ml_line_lnum == 0 || buf->b_ml.ml_mfp == NULL)
	return;		// nothing to do

    if (buf->b_ml.ml_flags & ML_LINE_DIRTY)
    {
	// This code doesn't work recursively, but Netbeans may call back here
	// when obtaining the cursor position.
	if (entered)
	    return;
	entered = TRUE;

	lnum = buf->b_ml.ml_line_lnum;
	new_line = buf->b_ml.ml_line_ptr;

	hp = ml_find_line(buf, lnum, ML_FIND);
	if (hp == NULL)
	    siemsg(_("E320: Cannot find line %ld"), lnum);
	else
	{
	    dp = (DATA_BL *)(hp->bh_data);
	    idx = lnum - buf->b_ml.ml_locked_low;
	    start = ((dp->db_index[idx]) & DB_INDEX_MASK);
	    old_line = (char_u *)dp + start;
	    if (idx == 0)	// line is last in block
		old_len = dp->db_txt_end - start;
	    else		// text of previous line follows
		old_len = (dp->db_index[idx - 1] & DB_INDEX_MASK) - start;
	    new_len = buf->b_ml.ml_line_len;
	    extra = new_len - old_len;	    // negative if lines gets smaller

	    /*
	     * if new line fits in data block, replace directly
	     */
	    if ((int)dp->db_free >= extra)
	    {
		// if the length changes and there are following lines
		count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1;
		if (extra != 0 && idx < count - 1)
		{
		    // move text of following lines
		    mch_memmove((char *)dp + dp->db_txt_start - extra,
				(char *)dp + dp->db_txt_start,
				(size_t)(start - dp->db_txt_start));

		    // adjust pointers of this and following lines
		    for (i = idx + 1; i < count; ++i)
			dp->db_index[i] -= extra;
		}
		dp->db_index[idx] -= extra;

		// adjust free space
		dp->db_free -= extra;
		dp->db_txt_start -= extra;

		// copy new line into the data block
		mch_memmove(old_line - extra, new_line, (size_t)new_len);
		buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
#ifdef FEAT_BYTEOFF
		// The else case is already covered by the insert and delete
		ml_updatechunk(buf, lnum, (long)extra, ML_CHNK_UPDLINE);
#endif
	    }
	    else
	    {
		/*
		 * Cannot do it in one data block: Delete and append.
		 * Append first, because ml_delete_int() cannot delete the
		 * last line in a buffer, which causes trouble for a buffer
		 * that has only one line.
		 * Don't forget to copy the mark!
		 */
		// How about handling errors???
		(void)ml_append_int(buf, lnum, new_line, new_len, FALSE,
					     (dp->db_index[idx] & DB_MARKED));
		(void)ml_delete_int(buf, lnum, FALSE);
	    }
	}
	vim_free(new_line);

	entered = FALSE;
    }

    buf->b_ml.ml_line_lnum = 0;
}

/*
 * create a new, empty, data block
 */
    static bhdr_T *
ml_new_data(memfile_T *mfp, int negative, int page_count)
{
    bhdr_T	*hp;
    DATA_BL	*dp;

    if ((hp = mf_new(mfp, negative, page_count)) == NULL)
	return NULL;

    dp = (DATA_BL *)(hp->bh_data);
    dp->db_id = DATA_ID;
    dp->db_txt_start = dp->db_txt_end = page_count * mfp->mf_page_size;
    dp->db_free = dp->db_txt_start - HEADER_SIZE;
    dp->db_line_count = 0;

    return hp;
}

/*
 * create a new, empty, pointer block
 */
    static bhdr_T *
ml_new_ptr(memfile_T *mfp)
{
    bhdr_T	*hp;
    PTR_BL	*pp;

    if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
	return NULL;

    pp = (PTR_BL *)(hp->bh_data);
    pp->pb_id = PTR_ID;
    pp->pb_count = 0;
    pp->pb_count_max = (short_u)((mfp->mf_page_size - sizeof(PTR_BL))
							/ sizeof(PTR_EN) + 1);

    return hp;
}

/*
 * Lookup line 'lnum' in a memline.
 *
 *   action: if ML_DELETE or ML_INSERT the line count is updated while searching
 *	     if ML_FLUSH only flush a locked block
 *	     if ML_FIND just find the line
 *
 * If the block was found it is locked and put in ml_locked.
 * The stack is updated to lead to the locked block. The ip_high field in
 * the stack is updated to reflect the last line in the block AFTER the
 * insert or delete, also if the pointer block has not been updated yet. But
 * if ml_locked != NULL ml_locked_lineadd must be added to ip_high.
 *
 * return: NULL for failure, pointer to block header otherwise
 */
    static bhdr_T *
ml_find_line(buf_T *buf, linenr_T lnum, int action)
{
    DATA_BL	*dp;
    PTR_BL	*pp;
    infoptr_T	*ip;
    bhdr_T	*hp;
    memfile_T	*mfp;
    linenr_T	t;
    blocknr_T	bnum, bnum2;
    int		dirty;
    linenr_T	low, high;
    int		top;
    int		page_count;
    int		idx;

    mfp = buf->b_ml.ml_mfp;

    /*
     * If there is a locked block check if the wanted line is in it.
     * If not, flush and release the locked block.
     * Don't do this for ML_INSERT_SAME, because the stack need to be updated.
     * Don't do this for ML_FLUSH, because we want to flush the locked block.
     * Don't do this when 'swapfile' is reset, we want to load all the blocks.
     */
    if (buf->b_ml.ml_locked)
    {
	if (ML_SIMPLE(action)
		&& buf->b_ml.ml_locked_low <= lnum
		&& buf->b_ml.ml_locked_high >= lnum
		&& !mf_dont_release)
	{
	    // remember to update pointer blocks and stack later
	    if (action == ML_INSERT)
	    {
		++(buf->b_ml.ml_locked_lineadd);
		++(buf->b_ml.ml_locked_high);
	    }
	    else if (action == ML_DELETE)
	    {
		--(buf->b_ml.ml_locked_lineadd);
		--(buf->b_ml.ml_locked_high);
	    }
	    return (buf->b_ml.ml_locked);
	}

	mf_put(mfp, buf->b_ml.ml_locked, buf->b_ml.ml_flags & ML_LOCKED_DIRTY,
					    buf->b_ml.ml_flags & ML_LOCKED_POS);
	buf->b_ml.ml_locked = NULL;

	/*
	 * If lines have been added or deleted in the locked block, need to
	 * update the line count in pointer blocks.
	 */
	if (buf->b_ml.ml_locked_lineadd != 0)
	    ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
    }

    if (action == ML_FLUSH)	    // nothing else to do
	return NULL;

    bnum = 1;			    // start at the root of the tree
    page_count = 1;
    low = 1;
    high = buf->b_ml.ml_line_count;

    if (action == ML_FIND)	// first try stack entries
    {
	for (top = buf->b_ml.ml_stack_top - 1; top >= 0; --top)
	{
	    ip = &(buf->b_ml.ml_stack[top]);
	    if (ip->ip_low <= lnum && ip->ip_high >= lnum)
	    {
		bnum = ip->ip_bnum;
		low = ip->ip_low;
		high = ip->ip_high;
		buf->b_ml.ml_stack_top = top;	// truncate stack at prev entry
		break;
	    }
	}
	if (top < 0)
	    buf->b_ml.ml_stack_top = 0;		// not found, start at the root
    }
    else	// ML_DELETE or ML_INSERT
	buf->b_ml.ml_stack_top = 0;	// start at the root

/*
 * search downwards in the tree until a data block is found
 */
    for (;;)
    {
	if ((hp = mf_get(mfp, bnum, page_count)) == NULL)
	    goto error_noblock;

	/*
	 * update high for insert/delete
	 */
	if (action == ML_INSERT)
	    ++high;
	else if (action == ML_DELETE)
	    --high;

	dp = (DATA_BL *)(hp->bh_data);
	if (dp->db_id == DATA_ID)	// data block
	{
	    buf->b_ml.ml_locked = hp;
	    buf->b_ml.ml_locked_low = low;
	    buf->b_ml.ml_locked_high = high;
	    buf->b_ml.ml_locked_lineadd = 0;
	    buf->b_ml.ml_flags &= ~(ML_LOCKED_DIRTY | ML_LOCKED_POS);
	    return hp;
	}

	pp = (PTR_BL *)(dp);		// must be pointer block
	if (pp->pb_id != PTR_ID)
	{
	    iemsg(_("E317: pointer block id wrong"));
	    goto error_block;
	}

	if ((top = ml_add_stack(buf)) < 0)	// add new entry to stack
	    goto error_block;
	ip = &(buf->b_ml.ml_stack[top]);
	ip->ip_bnum = bnum;
	ip->ip_low = low;
	ip->ip_high = high;
	ip->ip_index = -1;		// index not known yet

	dirty = FALSE;
	for (idx = 0; idx < (int)pp->pb_count; ++idx)
	{
	    t = pp->pb_pointer[idx].pe_line_count;
	    CHECK(t == 0, _("pe_line_count is zero"));
	    if ((low += t) > lnum)
	    {
		ip->ip_index = idx;
		bnum = pp->pb_pointer[idx].pe_bnum;
		page_count = pp->pb_pointer[idx].pe_page_count;
		high = low - 1;
		low -= t;

		/*
		 * a negative block number may have been changed
		 */
		if (bnum < 0)
		{
		    bnum2 = mf_trans_del(mfp, bnum);
		    if (bnum != bnum2)
		    {
			bnum = bnum2;
			pp->pb_pointer[idx].pe_bnum = bnum;
			dirty = TRUE;
		    }
		}

		break;
	    }
	}
	if (idx >= (int)pp->pb_count)	    // past the end: something wrong!
	{
	    if (lnum > buf->b_ml.ml_line_count)
		siemsg(_("E322: line number out of range: %ld past the end"),
					      lnum - buf->b_ml.ml_line_count);

	    else
		siemsg(_("E323: line count wrong in block %ld"), bnum);
	    goto error_block;
	}
	if (action == ML_DELETE)
	{
	    pp->pb_pointer[idx].pe_line_count--;
	    dirty = TRUE;
	}
	else if (action == ML_INSERT)
	{
	    pp->pb_pointer[idx].pe_line_count++;
	    dirty = TRUE;
	}
	mf_put(mfp, hp, dirty, FALSE);
    }

error_block:
    mf_put(mfp, hp, FALSE, FALSE);
error_noblock:
    /*
     * If action is ML_DELETE or ML_INSERT we have to correct the tree for
     * the incremented/decremented line counts, because there won't be a line
     * inserted/deleted after all.
     */
    if (action == ML_DELETE)
	ml_lineadd(buf, 1);
    else if (action == ML_INSERT)
	ml_lineadd(buf, -1);
    buf->b_ml.ml_stack_top = 0;
    return NULL;
}

/*
 * add an entry to the info pointer stack
 *
 * return -1 for failure, number of the new entry otherwise
 */
    static int
ml_add_stack(buf_T *buf)
{
    int		top;
    infoptr_T	*newstack;

    top = buf->b_ml.ml_stack_top;

    // may have to increase the stack size
    if (top == buf->b_ml.ml_stack_size)
    {
	CHECK(top > 0, _("Stack size increases")); // more than 5 levels???

	newstack = ALLOC_MULT(infoptr_T, buf->b_ml.ml_stack_size + STACK_INCR);
	if (newstack == NULL)
	    return -1;
	if (top > 0)
	    mch_memmove(newstack, buf->b_ml.ml_stack,
					     (size_t)top * sizeof(infoptr_T));
	vim_free(buf->b_ml.ml_stack);
	buf->b_ml.ml_stack = newstack;
	buf->b_ml.ml_stack_size += STACK_INCR;
    }

    buf->b_ml.ml_stack_top++;
    return top;
}

/*
 * Update the pointer blocks on the stack for inserted/deleted lines.
 * The stack itself is also updated.
 *
 * When a insert/delete line action fails, the line is not inserted/deleted,
 * but the pointer blocks have already been updated. That is fixed here by
 * walking through the stack.
 *
 * Count is the number of lines added, negative if lines have been deleted.
 */
    static void
ml_lineadd(buf_T *buf, int count)
{
    int		idx;
    infoptr_T	*ip;
    PTR_BL	*pp;
    memfile_T	*mfp = buf->b_ml.ml_mfp;
    bhdr_T	*hp;

    for (idx = buf->b_ml.ml_stack_top - 1; idx >= 0; --idx)
    {
	ip = &(buf->b_ml.ml_stack[idx]);
	if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
	    break;
	pp = (PTR_BL *)(hp->bh_data);	// must be pointer block
	if (pp->pb_id != PTR_ID)
	{
	    mf_put(mfp, hp, FALSE, FALSE);
	    iemsg(_("E317: pointer block id wrong 2"));
	    break;
	}
	pp->pb_pointer[ip->ip_index].pe_line_count += count;
	ip->ip_high += count;
	mf_put(mfp, hp, TRUE, FALSE);
    }
}

#if defined(HAVE_READLINK) || defined(PROTO)
/*
 * Resolve a symlink in the last component of a file name.
 * Note that f_resolve() does it for every part of the path, we don't do that
 * here.
 * If it worked returns OK and the resolved link in "buf[MAXPATHL]".
 * Otherwise returns FAIL.
 */
    int
resolve_symlink(char_u *fname, char_u *buf)
{
    char_u	tmp[MAXPATHL];
    int		ret;
    int		depth = 0;

    if (fname == NULL)
	return FAIL;

    // Put the result so far in tmp[], starting with the original name.
    vim_strncpy(tmp, fname, MAXPATHL - 1);

    for (;;)
    {
	// Limit symlink depth to 100, catch recursive loops.
	if (++depth == 100)
	{
	    semsg(_("E773: Symlink loop for \"%s\""), fname);
	    return FAIL;
	}

	ret = readlink((char *)tmp, (char *)buf, MAXPATHL - 1);
	if (ret <= 0)
	{
	    if (errno == EINVAL || errno == ENOENT)
	    {
		// Found non-symlink or not existing file, stop here.
		// When at the first level use the unmodified name, skip the
		// call to vim_FullName().
		if (depth == 1)
		    return FAIL;

		// Use the resolved name in tmp[].
		break;
	    }

	    // There must be some error reading links, use original name.
	    return FAIL;
	}
	buf[ret] = NUL;

	/*
	 * Check whether the symlink is relative or absolute.
	 * If it's relative, build a new path based on the directory
	 * portion of the filename (if any) and the path the symlink
	 * points to.
	 */
	if (mch_isFullName(buf))
	    STRCPY(tmp, buf);
	else
	{
	    char_u *tail;

	    tail = gettail(tmp);
	    if (STRLEN(tail) + STRLEN(buf) >= MAXPATHL)
		return FAIL;
	    STRCPY(tail, buf);
	}
    }

    /*
     * Try to resolve the full name of the file so that the swapfile name will
     * be consistent even when opening a relative symlink from different
     * working directories.
     */
    return vim_FullName(tmp, buf, MAXPATHL, TRUE);
}
#endif

/*
 * Make swap file name out of the file name and a directory name.
 * Returns pointer to allocated memory or NULL.
 */
    char_u *
makeswapname(
    char_u	*fname,
    char_u	*ffname UNUSED,
    buf_T	*buf,
    char_u	*dir_name)
{
    char_u	*r, *s;
    char_u	*fname_res = fname;
#ifdef HAVE_READLINK
    char_u	fname_buf[MAXPATHL];
#endif

#if defined(UNIX) || defined(MSWIN)  // Need _very_ long file names
    int		len = (int)STRLEN(dir_name);

    s = dir_name + len;
    if (after_pathsep(dir_name, s) && len > 1 && s[-1] == s[-2])
    {			       // Ends with '//', Use Full path
	r = NULL;
	if ((s = make_percent_swname(dir_name, fname)) != NULL)
	{
	    r = modname(s, (char_u *)".swp", FALSE);
	    vim_free(s);
	}
	return r;
    }
#endif

#ifdef HAVE_READLINK
    // Expand symlink in the file name, so that we put the swap file with the
    // actual file instead of with the symlink.
    if (resolve_symlink(fname, fname_buf) == OK)
	fname_res = fname_buf;
#endif

    r = buf_modname(
	    (buf->b_p_sn || buf->b_shortname),
	    fname_res,
	    (char_u *)
#if defined(VMS)
	    "_swp",
#else
	    ".swp",
#endif
	    // Prepend a '.' to the swap file name for the current directory.
	    dir_name[0] == '.' && dir_name[1] == NUL);
    if (r == NULL)	    // out of memory
	return NULL;

    s = get_file_in_dir(r, dir_name);
    vim_free(r);
    return s;
}

/*
 * Get file name to use for swap file or backup file.
 * Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir'
 * option "dname".
 * - If "dname" is ".", return "fname" (swap file in dir of file).
 * - If "dname" starts with "./", insert "dname" in "fname" (swap file
 *   relative to dir of file).
 * - Otherwise, prepend "dname" to the tail of "fname" (swap file in specific
 *   dir).
 *
 * The return value is an allocated string and can be NULL.
 */
    char_u *
get_file_in_dir(
    char_u  *fname,
    char_u  *dname)	// don't use "dirname", it is a global for Alpha
{
    char_u	*t;
    char_u	*tail;
    char_u	*retval;
    int		save_char;

    tail = gettail(fname);

    if (dname[0] == '.' && dname[1] == NUL)
	retval = vim_strsave(fname);
    else if (dname[0] == '.' && vim_ispathsep(dname[1]))
    {
	if (tail == fname)	    // no path before file name
	    retval = concat_fnames(dname + 2, tail, TRUE);
	else
	{
	    save_char = *tail;
	    *tail = NUL;
	    t = concat_fnames(fname, dname + 2, TRUE);
	    *tail = save_char;
	    if (t == NULL)	    // out of memory
		retval = NULL;
	    else
	    {
		retval = concat_fnames(t, tail, TRUE);
		vim_free(t);
	    }
	}
    }
    else
	retval = concat_fnames(dname, tail, TRUE);

#ifdef MSWIN
    if (retval != NULL)
	for (t = gettail(retval); *t != NUL; MB_PTR_ADV(t))
	    if (*t == ':')
		*t = '%';
#endif

    return retval;
}

/*
 * Print the ATTENTION message: info about an existing swap file.
 */
    static void
attention_message(
    buf_T   *buf,	// buffer being edited
    char_u  *fname)	// swap file name
{
    stat_T	st;
    time_t	swap_mtime;

    ++no_wait_return;
    (void)emsg(_("E325: ATTENTION"));
    msg_puts(_("\nFound a swap file by the name \""));
    msg_home_replace(fname);
    msg_puts("\"\n");
    swap_mtime = swapfile_info(fname);
    msg_puts(_("While opening file \""));
    msg_outtrans(buf->b_fname);
    msg_puts("\"\n");
    if (mch_stat((char *)buf->b_fname, &st) == -1)
    {
	msg_puts(_("      CANNOT BE FOUND"));
    }
    else
    {
	msg_puts(_("             dated: "));
	msg_puts(get_ctime(st.st_mtime, TRUE));
	if (swap_mtime != 0 && st.st_mtime > swap_mtime)
	    msg_puts(_("      NEWER than swap file!\n"));
    }
    // Some of these messages are long to allow translation to
    // other languages.
    msg_puts(_("\n(1) Another program may be editing the same file.  If this is the case,\n    be careful not to end up with two different instances of the same\n    file when making changes.  Quit, or continue with caution.\n"));
    msg_puts(_("(2) An edit session for this file crashed.\n"));
    msg_puts(_("    If this is the case, use \":recover\" or \"vim -r "));
    msg_outtrans(buf->b_fname);
    msg_puts(_("\"\n    to recover the changes (see \":help recovery\").\n"));
    msg_puts(_("    If you did this already, delete the swap file \""));
    msg_outtrans(fname);
    msg_puts(_("\"\n    to avoid this message.\n"));
    cmdline_row = msg_row;
    --no_wait_return;
}

#if defined(FEAT_EVAL)
/*
 * Trigger the SwapExists autocommands.
 * Returns a value for equivalent to do_dialog() (see below):
 * 0: still need to ask for a choice
 * 1: open read-only
 * 2: edit anyway
 * 3: recover
 * 4: delete it
 * 5: quit
 * 6: abort
 */
    static int
do_swapexists(buf_T *buf, char_u *fname)
{
    set_vim_var_string(VV_SWAPNAME, fname, -1);
    set_vim_var_string(VV_SWAPCHOICE, NULL, -1);

    // Trigger SwapExists autocommands with <afile> set to the file being
    // edited.  Disallow changing directory here.
    ++allbuf_lock;
    apply_autocmds(EVENT_SWAPEXISTS, buf->b_fname, NULL, FALSE, NULL);
    --allbuf_lock;

    set_vim_var_string(VV_SWAPNAME, NULL, -1);

    switch (*get_vim_var_str(VV_SWAPCHOICE))
    {
	case 'o': return 1;
	case 'e': return 2;
	case 'r': return 3;
	case 'd': return 4;
	case 'q': return 5;
	case 'a': return 6;
    }

    return 0;
}
#endif

/*
 * Find out what name to use for the swap file for buffer 'buf'.
 *
 * Several names are tried to find one that does not exist
 * Returns the name in allocated memory or NULL.
 * When out of memory "dirp" is set to NULL.
 *
 * Note: If BASENAMELEN is not correct, you will get error messages for
 *	 not being able to open the swap or undo file
 * Note: May trigger SwapExists autocmd, pointers may change!
 */
    static char_u *
findswapname(
    buf_T	*buf,
    char_u	**dirp,		// pointer to list of directories
    char_u	*old_fname)	// don't give warning for this file name
{
    char_u	*fname;
    int		n;
    char_u	*dir_name;
#ifdef AMIGA
    BPTR	fh;
#endif
    int		r;
    char_u	*buf_fname = buf->b_fname;

#if !defined(UNIX)
# define CREATE_DUMMY_FILE
    FILE	*dummyfd = NULL;

# ifdef MSWIN
    if (buf_fname != NULL && !mch_isFullName(buf_fname)
				       && vim_strchr(gettail(buf_fname), ':'))
    {
	char_u *t;

	buf_fname = vim_strsave(buf_fname);
	if (buf_fname == NULL)
	    buf_fname = buf->b_fname;
	else
	    for (t = gettail(buf_fname); *t != NUL; MB_PTR_ADV(t))
		if (*t == ':')
		    *t = '%';
    }
# endif

    /*
     * If we start editing a new file, e.g. "test.doc", which resides on an
     * MSDOS compatible filesystem, it is possible that the file
     * "test.doc.swp" which we create will be exactly the same file. To avoid
     * this problem we temporarily create "test.doc".  Don't do this when the
     * check below for a 8.3 file name is used.
     */
    if (!(buf->b_p_sn || buf->b_shortname) && buf_fname != NULL
					     && mch_getperm(buf_fname) < 0)
	dummyfd = mch_fopen((char *)buf_fname, "w");
#endif

    /*
     * Isolate a directory name from *dirp and put it in dir_name.
     * First allocate some memory to put the directory name in.
     */
    dir_name = alloc(STRLEN(*dirp) + 1);
    if (dir_name == NULL)
	*dirp = NULL;
    else
	(void)copy_option_part(dirp, dir_name, 31000, ",");

    /*
     * we try different names until we find one that does not exist yet
     */
    if (dir_name == NULL)	    // out of memory
	fname = NULL;
    else
	fname = makeswapname(buf_fname, buf->b_ffname, buf, dir_name);

    for (;;)
    {
	if (fname == NULL)	// must be out of memory
	    break;
	if ((n = (int)STRLEN(fname)) == 0)	// safety check
	{
	    VIM_CLEAR(fname);
	    break;
	}
#if defined(UNIX)
/*
 * Some systems have a MS-DOS compatible filesystem that use 8.3 character
 * file names. If this is the first try and the swap file name does not fit in
 * 8.3, detect if this is the case, set shortname and try again.
 */
	if (fname[n - 2] == 'w' && fname[n - 1] == 'p'
					&& !(buf->b_p_sn || buf->b_shortname))
	{
	    char_u	    *tail;
	    char_u	    *fname2;
	    stat_T	    s1, s2;
	    int		    f1, f2;
	    int		    created1 = FALSE, created2 = FALSE;
	    int		    same = FALSE;

	    /*
	     * Check if swapfile name does not fit in 8.3:
	     * It either contains two dots, is longer than 8 chars, or starts
	     * with a dot.
	     */
	    tail = gettail(buf_fname);
	    if (       vim_strchr(tail, '.') != NULL
		    || STRLEN(tail) > (size_t)8
		    || *gettail(fname) == '.')
	    {
		fname2 = alloc(n + 2);
		if (fname2 != NULL)
		{
		    STRCPY(fname2, fname);
		    // if fname == "xx.xx.swp",	    fname2 = "xx.xx.swx"
		    // if fname == ".xx.swp",	    fname2 = ".xx.swpx"
		    // if fname == "123456789.swp", fname2 = "12345678x.swp"
		    if (vim_strchr(tail, '.') != NULL)
			fname2[n - 1] = 'x';
		    else if (*gettail(fname) == '.')
		    {
			fname2[n] = 'x';
			fname2[n + 1] = NUL;
		    }
		    else
			fname2[n - 5] += 1;
		    /*
		     * may need to create the files to be able to use mch_stat()
		     */
		    f1 = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
		    if (f1 < 0)
		    {
			f1 = mch_open_rw((char *)fname,
					       O_RDWR|O_CREAT|O_EXCL|O_EXTRA);
			created1 = TRUE;
		    }
		    if (f1 >= 0)
		    {
			f2 = mch_open((char *)fname2, O_RDONLY | O_EXTRA, 0);
			if (f2 < 0)
			{
			    f2 = mch_open_rw((char *)fname2,
					       O_RDWR|O_CREAT|O_EXCL|O_EXTRA);
			    created2 = TRUE;
			}
			if (f2 >= 0)
			{
			    /*
			     * Both files exist now. If mch_stat() returns the
			     * same device and inode they are the same file.
			     */
			    if (mch_fstat(f1, &s1) != -1
				    && mch_fstat(f2, &s2) != -1
				    && s1.st_dev == s2.st_dev
				    && s1.st_ino == s2.st_ino)
				same = TRUE;
			    close(f2);
			    if (created2)
				mch_remove(fname2);
			}
			close(f1);
			if (created1)
			    mch_remove(fname);
		    }
		    vim_free(fname2);
		    if (same)
		    {
			buf->b_shortname = TRUE;
			vim_free(fname);
			fname = makeswapname(buf_fname, buf->b_ffname,
							       buf, dir_name);
			continue;	// try again with b_shortname set
		    }
		}
	    }
	}
#endif
	/*
	 * check if the swapfile already exists
	 */
	if (mch_getperm(fname) < 0)	// it does not exist
	{
#ifdef HAVE_LSTAT
	    stat_T	sb;

	    /*
	     * Extra security check: When a swap file is a symbolic link, this
	     * is most likely a symlink attack.
	     */
	    if (mch_lstat((char *)fname, &sb) < 0)
#else
# ifdef AMIGA
	    fh = Open((UBYTE *)fname, (long)MODE_NEWFILE);
	    /*
	     * on the Amiga mch_getperm() will return -1 when the file exists
	     * but is being used by another program. This happens if you edit
	     * a file twice.
	     */
	    if (fh != (BPTR)NULL)	// can open file, OK
	    {
		Close(fh);
		mch_remove(fname);
		break;
	    }
	    if (IoErr() != ERROR_OBJECT_IN_USE
					    && IoErr() != ERROR_OBJECT_EXISTS)
# endif
#endif
		break;
	}

	/*
	 * A file name equal to old_fname is OK to use.
	 */
	if (old_fname != NULL && fnamecmp(fname, old_fname) == 0)
	    break;

	/*
	 * get here when file already exists
	 */
	if (fname[n - 2] == 'w' && fname[n - 1] == 'p')	// first try
	{
	    /*
	     * on MS-DOS compatible filesystems (e.g. messydos) file.doc.swp
	     * and file.doc are the same file. To guess if this problem is
	     * present try if file.doc.swx exists. If it does, we set
	     * buf->b_shortname and try file_doc.swp (dots replaced by
	     * underscores for this file), and try again. If it doesn't we
	     * assume that "file.doc.swp" already exists.
	     */
	    if (!(buf->b_p_sn || buf->b_shortname))	// not tried yet
	    {
		fname[n - 1] = 'x';
		r = mch_getperm(fname);		// try "file.swx"
		fname[n - 1] = 'p';
		if (r >= 0)		    // "file.swx" seems to exist
		{
		    buf->b_shortname = TRUE;
		    vim_free(fname);
		    fname = makeswapname(buf_fname, buf->b_ffname,
							       buf, dir_name);
		    continue;	    // try again with '.' replaced with '_'
		}
	    }
	    /*
	     * If we get here the ".swp" file really exists.
	     * Give an error message, unless recovering, no file name, we are
	     * viewing a help file or when the path of the file is different
	     * (happens when all .swp files are in one directory).
	     */
	    if (!recoverymode && buf_fname != NULL
				&& !buf->b_help
				&& !(buf->b_flags & (BF_DUMMY | BF_NO_SEA)))
	    {
		int		fd;
		struct block0	b0;
		int		differ = FALSE;

		/*
		 * Try to read block 0 from the swap file to get the original
		 * file name (and inode number).
		 */
		fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
		if (fd >= 0)
		{
		    if (read_eintr(fd, &b0, sizeof(b0)) == sizeof(b0))
		    {
			/*
			 * If the swapfile has the same directory as the
			 * buffer don't compare the directory names, they can
			 * have a different mountpoint.
			 */
			if (b0.b0_flags & B0_SAME_DIR)
			{
			    if (fnamecmp(gettail(buf->b_ffname),
						   gettail(b0.b0_fname)) != 0
				    || !same_directory(fname, buf->b_ffname))
			    {
#ifdef CHECK_INODE
				// Symlinks may point to the same file even
				// when the name differs, need to check the
				// inode too.
				expand_env(b0.b0_fname, NameBuff, MAXPATHL);
				if (fnamecmp_ino(buf->b_ffname, NameBuff,
						     char_to_long(b0.b0_ino)))
#endif
				    differ = TRUE;
			    }
			}
			else
			{
			    /*
			     * The name in the swap file may be
			     * "~user/path/file".  Expand it first.
			     */
			    expand_env(b0.b0_fname, NameBuff, MAXPATHL);
#ifdef CHECK_INODE
			    if (fnamecmp_ino(buf->b_ffname, NameBuff,
						     char_to_long(b0.b0_ino)))
				differ = TRUE;
#else
			    if (fnamecmp(NameBuff, buf->b_ffname) != 0)
				differ = TRUE;
#endif
			}
		    }
		    close(fd);
		}

		// give the ATTENTION message when there is an old swap file
		// for the current file, and the buffer was not recovered.
		if (differ == FALSE && !(curbuf->b_flags & BF_RECOVERED)
			&& vim_strchr(p_shm, SHM_ATTENTION) == NULL)
		{
		    int		choice = 0;
		    stat_T	st;
#ifdef CREATE_DUMMY_FILE
		    int		did_use_dummy = FALSE;

		    // Avoid getting a warning for the file being created
		    // outside of Vim, it was created at the start of this
		    // function.  Delete the file now, because Vim might exit
		    // here if the window is closed.
		    if (dummyfd != NULL)
		    {
			fclose(dummyfd);
			dummyfd = NULL;
			mch_remove(buf_fname);
			did_use_dummy = TRUE;
		    }
#endif

#ifdef HAVE_PROCESS_STILL_RUNNING
		    process_still_running = FALSE;
#endif
		    // It's safe to delete the swap file if all these are true:
		    // - the edited file exists
		    // - the swap file has no changes and looks OK
		    if (mch_stat((char *)buf->b_fname, &st) == 0
						  && swapfile_unchanged(fname))
		    {
			choice = 4;
			if (p_verbose > 0)
			    verb_msg(_("Found a swap file that is not useful, deleting it"));
		    }

#if defined(FEAT_EVAL)
		    /*
		     * If there is an SwapExists autocommand and we can handle
		     * the response, trigger it.  It may return 0 to ask the
		     * user anyway.
		     */
		    if (choice == 0
			    && swap_exists_action != SEA_NONE
			    && has_autocmd(EVENT_SWAPEXISTS, buf_fname, buf))
			choice = do_swapexists(buf, fname);

		    if (choice == 0)
#endif
		    {
#ifdef FEAT_GUI
			// If we are supposed to start the GUI but it wasn't
			// completely started yet, start it now.  This makes
			// the messages displayed in the Vim window when
			// loading a session from the .gvimrc file.
			if (gui.starting && !gui.in_use)
			    gui_start(NULL);
#endif
			// Show info about the existing swap file.
			attention_message(buf, fname);

			// We don't want a 'q' typed at the more-prompt
			// interrupt loading a file.
			got_int = FALSE;

			// If vimrc has "simalt ~x" we don't want it to
			// interfere with the prompt here.
			flush_buffers(FLUSH_TYPEAHEAD);
		    }

#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
		    if (swap_exists_action != SEA_NONE && choice == 0)
		    {
			char_u	*name;

			name = alloc(STRLEN(fname)
				+ STRLEN(_("Swap file \""))
				+ STRLEN(_("\" already exists!")) + 5);
			if (name != NULL)
			{
			    STRCPY(name, _("Swap file \""));
			    home_replace(NULL, fname, name + STRLEN(name),
								  1000, TRUE);
			    STRCAT(name, _("\" already exists!"));
			}
			choice = do_dialog(VIM_WARNING,
				    (char_u *)_("VIM - ATTENTION"),
				    name == NULL
					?  (char_u *)_("Swap file already exists!")
					: name,
# ifdef HAVE_PROCESS_STILL_RUNNING
				    process_still_running
					? (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover\n&Quit\n&Abort") :
# endif
					(char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover\n&Delete it\n&Quit\n&Abort"), 1, NULL, FALSE);

# ifdef HAVE_PROCESS_STILL_RUNNING
			if (process_still_running && choice >= 4)
			    choice++;	// Skip missing "Delete it" button
# endif
			vim_free(name);

			// pretend screen didn't scroll, need redraw anyway
			msg_scrolled = 0;
			redraw_all_later(NOT_VALID);
		    }
#endif

		    if (choice > 0)
		    {
			switch (choice)
			{
			    case 1:
				buf->b_p_ro = TRUE;
				break;
			    case 2:
				break;
			    case 3:
				swap_exists_action = SEA_RECOVER;
				break;
			    case 4:
				mch_remove(fname);
				break;
			    case 5:
				swap_exists_action = SEA_QUIT;
				break;
			    case 6:
				swap_exists_action = SEA_QUIT;
				got_int = TRUE;
				break;
			}

			// If the file was deleted this fname can be used.
			if (mch_getperm(fname) < 0)
			    break;
		    }
		    else
		    {
			msg_puts("\n");
			if (msg_silent == 0)
			    // call wait_return() later
			    need_wait_return = TRUE;
		    }

#ifdef CREATE_DUMMY_FILE
		    // Going to try another name, need the dummy file again.
		    if (did_use_dummy)
			dummyfd = mch_fopen((char *)buf_fname, "w");
#endif
		}
	    }
	}

	/*
	 * Change the ".swp" extension to find another file that can be used.
	 * First decrement the last char: ".swo", ".swn", etc.
	 * If that still isn't enough decrement the last but one char: ".svz"
	 * Can happen when editing many "No Name" buffers.
	 */
	if (fname[n - 1] == 'a')	// ".s?a"
	{
	    if (fname[n - 2] == 'a')    // ".saa": tried enough, give up
	    {
		emsg(_("E326: Too many swap files found"));
		VIM_CLEAR(fname);
		break;
	    }
	    --fname[n - 2];		// ".svz", ".suz", etc.
	    fname[n - 1] = 'z' + 1;
	}
	--fname[n - 1];			// ".swo", ".swn", etc.
    }

    vim_free(dir_name);
#ifdef CREATE_DUMMY_FILE
    if (dummyfd != NULL)	// file has been created temporarily
    {
	fclose(dummyfd);
	mch_remove(buf_fname);
    }
#endif
#ifdef MSWIN
    if (buf_fname != buf->b_fname)
	vim_free(buf_fname);
#endif
    return fname;
}

    static int
b0_magic_wrong(ZERO_BL *b0p)
{
    return (b0p->b0_magic_long != (long)B0_MAGIC_LONG
	    || b0p->b0_magic_int != (int)B0_MAGIC_INT
	    || b0p->b0_magic_short != (short)B0_MAGIC_SHORT
	    || b0p->b0_magic_char != B0_MAGIC_CHAR);
}

#ifdef CHECK_INODE
/*
 * Compare current file name with file name from swap file.
 * Try to use inode numbers when possible.
 * Return non-zero when files are different.
 *
 * When comparing file names a few things have to be taken into consideration:
 * - When working over a network the full path of a file depends on the host.
 *   We check the inode number if possible.  It is not 100% reliable though,
 *   because the device number cannot be used over a network.
 * - When a file does not exist yet (editing a new file) there is no inode
 *   number.
 * - The file name in a swap file may not be valid on the current host.  The
 *   "~user" form is used whenever possible to avoid this.
 *
 * This is getting complicated, let's make a table:
 *
 *		ino_c  ino_s  fname_c  fname_s	differ =
 *
 * both files exist -> compare inode numbers:
 *		!= 0   != 0	X	 X	ino_c != ino_s
 *
 * inode number(s) unknown, file names available -> compare file names
 *		== 0	X	OK	 OK	fname_c != fname_s
 *		 X     == 0	OK	 OK	fname_c != fname_s
 *
 * current file doesn't exist, file for swap file exist, file name(s) not
 * available -> probably different
 *		== 0   != 0    FAIL	 X	TRUE
 *		== 0   != 0	X	FAIL	TRUE
 *
 * current file exists, inode for swap unknown, file name(s) not
 * available -> probably different
 *		!= 0   == 0    FAIL	 X	TRUE
 *		!= 0   == 0	X	FAIL	TRUE
 *
 * current file doesn't exist, inode for swap unknown, one file name not
 * available -> probably different
 *		== 0   == 0    FAIL	 OK	TRUE
 *		== 0   == 0	OK	FAIL	TRUE
 *
 * current file doesn't exist, inode for swap unknown, both file names not
 * available -> compare file names
 *		== 0   == 0    FAIL	FAIL	fname_c != fname_s
 *
 * Note that when the ino_t is 64 bits, only the last 32 will be used.  This
 * can't be changed without making the block 0 incompatible with 32 bit
 * versions.
 */

    static int
fnamecmp_ino(
    char_u	*fname_c,	    // current file name
    char_u	*fname_s,	    // file name from swap file
    long	ino_block0)
{
    stat_T	st;
    ino_t	ino_c = 0;	    // ino of current file
    ino_t	ino_s;		    // ino of file from swap file
    char_u	buf_c[MAXPATHL];    // full path of fname_c
    char_u	buf_s[MAXPATHL];    // full path of fname_s
    int		retval_c;	    // flag: buf_c valid
    int		retval_s;	    // flag: buf_s valid

    if (mch_stat((char *)fname_c, &st) == 0)
	ino_c = (ino_t)st.st_ino;

    /*
     * First we try to get the inode from the file name, because the inode in
     * the swap file may be outdated.  If that fails (e.g. this path is not
     * valid on this machine), use the inode from block 0.
     */
    if (mch_stat((char *)fname_s, &st) == 0)
	ino_s = (ino_t)st.st_ino;
    else
	ino_s = (ino_t)ino_block0;

    if (ino_c && ino_s)
	return (ino_c != ino_s);

    /*
     * One of the inode numbers is unknown, try a forced vim_FullName() and
     * compare the file names.
     */
    retval_c = vim_FullName(fname_c, buf_c, MAXPATHL, TRUE);
    retval_s = vim_FullName(fname_s, buf_s, MAXPATHL, TRUE);
    if (retval_c == OK && retval_s == OK)
	return STRCMP(buf_c, buf_s) != 0;

    /*
     * Can't compare inodes or file names, guess that the files are different,
     * unless both appear not to exist at all, then compare with the file name
     * in the swap file.
     */
    if (ino_s == 0 && ino_c == 0 && retval_c == FAIL && retval_s == FAIL)
	return STRCMP(fname_c, fname_s) != 0;
    return TRUE;
}
#endif // CHECK_INODE

/*
 * Move a long integer into a four byte character array.
 * Used for machine independency in block zero.
 */
    static void
long_to_char(long n, char_u *s)
{
    s[0] = (char_u)(n & 0xff);
    n = (unsigned)n >> 8;
    s[1] = (char_u)(n & 0xff);
    n = (unsigned)n >> 8;
    s[2] = (char_u)(n & 0xff);
    n = (unsigned)n >> 8;
    s[3] = (char_u)(n & 0xff);
}

    static long
char_to_long(char_u *s)
{
    long    retval;

    retval = s[3];
    retval <<= 8;
    retval |= s[2];
    retval <<= 8;
    retval |= s[1];
    retval <<= 8;
    retval |= s[0];

    return retval;
}

/*
 * Set the flags in the first block of the swap file:
 * - file is modified or not: buf->b_changed
 * - 'fileformat'
 * - 'fileencoding'
 */
    void
ml_setflags(buf_T *buf)
{
    bhdr_T	*hp;
    ZERO_BL	*b0p;

    if (!buf->b_ml.ml_mfp)
	return;
    for (hp = buf->b_ml.ml_mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
    {
	if (hp->bh_bnum == 0)
	{
	    b0p = (ZERO_BL *)(hp->bh_data);
	    b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
	    b0p->b0_flags = (b0p->b0_flags & ~B0_FF_MASK)
						  | (get_fileformat(buf) + 1);
	    add_b0_fenc(b0p, buf);
	    hp->bh_flags |= BH_DIRTY;
	    mf_sync(buf->b_ml.ml_mfp, MFS_ZERO);
	    break;
	}
    }
}

#if defined(FEAT_CRYPT) || defined(PROTO)
/*
 * If "data" points to a data block encrypt the text in it and return a copy
 * in allocated memory.  Return NULL when out of memory.
 * Otherwise return "data".
 */
    char_u *
ml_encrypt_data(
    memfile_T	*mfp,
    char_u	*data,
    off_T	offset,
    unsigned	size)
{
    DATA_BL	*dp = (DATA_BL *)data;
    char_u	*head_end;
    char_u	*text_start;
    char_u	*new_data;
    int		text_len;
    cryptstate_T *state;

    if (dp->db_id != DATA_ID)
	return data;

    state = ml_crypt_prepare(mfp, offset, FALSE);
    if (state == NULL)
	return data;

    new_data = alloc(size);
    if (new_data == NULL)
	return NULL;
    head_end = (char_u *)(&dp->db_index[dp->db_line_count]);
    text_start = (char_u *)dp + dp->db_txt_start;
    text_len = size - dp->db_txt_start;

    // Copy the header and the text.
    mch_memmove(new_data, dp, head_end - (char_u *)dp);

    // Encrypt the text.
    crypt_encode(state, text_start, text_len, new_data + dp->db_txt_start);
    crypt_free_state(state);

    // Clear the gap.
    if (head_end < text_start)
	vim_memset(new_data + (head_end - data), 0, text_start - head_end);

    return new_data;
}

/*
 * Decrypt the text in "data" if it points to an encrypted data block.
 */
    void
ml_decrypt_data(
    memfile_T	*mfp,
    char_u	*data,
    off_T	offset,
    unsigned	size)
{
    DATA_BL	*dp = (DATA_BL *)data;
    char_u	*head_end;
    char_u	*text_start;
    int		text_len;
    cryptstate_T *state;

    if (dp->db_id == DATA_ID)
    {
	head_end = (char_u *)(&dp->db_index[dp->db_line_count]);
	text_start = (char_u *)dp + dp->db_txt_start;
	text_len = dp->db_txt_end - dp->db_txt_start;

	if (head_end > text_start || dp->db_txt_start > size
						     || dp->db_txt_end > size)
	    return;  // data was messed up

	state = ml_crypt_prepare(mfp, offset, TRUE);
	if (state != NULL)
	{
	    // Decrypt the text in place.
	    crypt_decode_inplace(state, text_start, text_len);
	    crypt_free_state(state);
	}
    }
}

/*
 * Prepare for encryption/decryption, using the key, seed and offset.
 * Return an allocated cryptstate_T *.
 */
    static cryptstate_T *
ml_crypt_prepare(memfile_T *mfp, off_T offset, int reading)
{
    buf_T	*buf = mfp->mf_buffer;
    char_u	salt[50];
    int		method_nr;
    char_u	*key;
    char_u	*seed;

    if (reading && mfp->mf_old_key != NULL)
    {
	// Reading back blocks with the previous key/method/seed.
	method_nr = mfp->mf_old_cm;
	key = mfp->mf_old_key;
	seed = mfp->mf_old_seed;
    }
    else
    {
	method_nr = crypt_get_method_nr(buf);
	key = buf->b_p_key;
	seed = mfp->mf_seed;
    }
    if (*key == NUL)
	return NULL;

    if (method_nr == CRYPT_M_ZIP)
    {
	// For PKzip: Append the offset to the key, so that we use a different
	// key for every block.
	vim_snprintf((char *)salt, sizeof(salt), "%s%ld", key, (long)offset);
	return crypt_create(method_nr, salt, NULL, 0, NULL, 0);
    }

    // Using blowfish or better: add salt and seed. We use the byte offset
    // of the block for the salt.
    vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset);
    return crypt_create(method_nr, key, salt, (int)STRLEN(salt),
							   seed, MF_SEED_LEN);
}

#endif


#if defined(FEAT_BYTEOFF) || defined(PROTO)

#define MLCS_MAXL 800	// max no of lines in chunk
#define MLCS_MINL 400   // should be half of MLCS_MAXL

/*
 * Keep information for finding byte offset of a line, updtype may be one of:
 * ML_CHNK_ADDLINE: Add len to parent chunk, possibly splitting it
 *	   Careful: ML_CHNK_ADDLINE may cause ml_find_line() to be called.
 * ML_CHNK_DELLINE: Subtract len from parent chunk, possibly deleting it
 * ML_CHNK_UPDLINE: Add len to parent chunk, as a signed entity.
 */
    static void
ml_updatechunk(
    buf_T	*buf,
    linenr_T	line,
    long	len,
    int		updtype)
{
    static buf_T	*ml_upd_lastbuf = NULL;
    static linenr_T	ml_upd_lastline;
    static linenr_T	ml_upd_lastcurline;
    static int		ml_upd_lastcurix;

    linenr_T		curline = ml_upd_lastcurline;
    int			curix = ml_upd_lastcurix;
    long		size;
    chunksize_T		*curchnk;
    int			rest;
    bhdr_T		*hp;
    DATA_BL		*dp;

    if (buf->b_ml.ml_usedchunks == -1 || len == 0)
	return;
    if (buf->b_ml.ml_chunksize == NULL)
    {
	buf->b_ml.ml_chunksize = ALLOC_MULT(chunksize_T, 100);
	if (buf->b_ml.ml_chunksize == NULL)
	{
	    buf->b_ml.ml_usedchunks = -1;
	    return;
	}
	buf->b_ml.ml_numchunks = 100;
	buf->b_ml.ml_usedchunks = 1;
	buf->b_ml.ml_chunksize[0].mlcs_numlines = 1;
	buf->b_ml.ml_chunksize[0].mlcs_totalsize = 1;
    }

    if (updtype == ML_CHNK_UPDLINE && buf->b_ml.ml_line_count == 1)
    {
	/*
	 * First line in empty buffer from ml_flush_line() -- reset
	 */
	buf->b_ml.ml_usedchunks = 1;
	buf->b_ml.ml_chunksize[0].mlcs_numlines = 1;
	buf->b_ml.ml_chunksize[0].mlcs_totalsize = (long)buf->b_ml.ml_line_len;
	return;
    }

    /*
     * Find chunk that our line belongs to, curline will be at start of the
     * chunk.
     */
    if (buf != ml_upd_lastbuf || line != ml_upd_lastline + 1
	    || updtype != ML_CHNK_ADDLINE)
    {
	for (curline = 1, curix = 0;
	     curix < buf->b_ml.ml_usedchunks - 1
	     && line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines;
	     curix++)
	    curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
    }
    else if (curix < buf->b_ml.ml_usedchunks - 1
	      && line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines)
    {
	// Adjust cached curix & curline
	curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
	curix++;
    }
    curchnk = buf->b_ml.ml_chunksize + curix;

    if (updtype == ML_CHNK_DELLINE)
	len = -len;
    curchnk->mlcs_totalsize += len;
    if (updtype == ML_CHNK_ADDLINE)
    {
	curchnk->mlcs_numlines++;

	// May resize here so we don't have to do it in both cases below
	if (buf->b_ml.ml_usedchunks + 1 >= buf->b_ml.ml_numchunks)
	{
	    chunksize_T *t_chunksize = buf->b_ml.ml_chunksize;

	    buf->b_ml.ml_numchunks = buf->b_ml.ml_numchunks * 3 / 2;
	    buf->b_ml.ml_chunksize = (chunksize_T *)
		vim_realloc(buf->b_ml.ml_chunksize,
			    sizeof(chunksize_T) * buf->b_ml.ml_numchunks);
	    if (buf->b_ml.ml_chunksize == NULL)
	    {
		// Hmmmm, Give up on offset for this buffer
		vim_free(t_chunksize);
		buf->b_ml.ml_usedchunks = -1;
		return;
	    }
	}

	if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL)
	{
	    int	    count;	    // number of entries in block
	    int	    idx;
	    int	    end_idx;
	    int	    text_end;
	    int	    linecnt;

	    mch_memmove(buf->b_ml.ml_chunksize + curix + 1,
			buf->b_ml.ml_chunksize + curix,
			(buf->b_ml.ml_usedchunks - curix) *
			sizeof(chunksize_T));
	    // Compute length of first half of lines in the split chunk
	    size = 0;
	    linecnt = 0;
	    while (curline < buf->b_ml.ml_line_count
			&& linecnt < MLCS_MINL)
	    {
		if ((hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
		{
		    buf->b_ml.ml_usedchunks = -1;
		    return;
		}
		dp = (DATA_BL *)(hp->bh_data);
		count = (long)(buf->b_ml.ml_locked_high) -
			(long)(buf->b_ml.ml_locked_low) + 1;
		idx = curline - buf->b_ml.ml_locked_low;
		curline = buf->b_ml.ml_locked_high + 1;

		// compute index of last line to use in this MEMLINE
		rest = count - idx;
		if (linecnt + rest > MLCS_MINL)
		{
		    end_idx = idx + MLCS_MINL - linecnt - 1;
		    linecnt = MLCS_MINL;
		}
		else
		{
		    end_idx = count - 1;
		    linecnt += rest;
		}
#ifdef FEAT_PROP_POPUP
		if (buf->b_has_textprop)
		{
		    int i;

		    // We cannot use the text pointers to get the text length,
		    // the text prop info would also be counted.  Go over the
		    // lines.
		    for (i = end_idx; i < idx; ++i)
			size += (int)STRLEN((char_u *)dp + (dp->db_index[i] & DB_INDEX_MASK)) + 1;
		}
		else
#endif
		{
		    if (idx == 0)// first line in block, text at the end
			text_end = dp->db_txt_end;
		    else
			text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
		    size += text_end - ((dp->db_index[end_idx]) & DB_INDEX_MASK);
		}
	    }
	    buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt;
	    buf->b_ml.ml_chunksize[curix + 1].mlcs_numlines -= linecnt;
	    buf->b_ml.ml_chunksize[curix].mlcs_totalsize = size;
	    buf->b_ml.ml_chunksize[curix + 1].mlcs_totalsize -= size;
	    buf->b_ml.ml_usedchunks++;
	    ml_upd_lastbuf = NULL;   // Force recalc of curix & curline
	    return;
	}
	else if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MINL
		     && curix == buf->b_ml.ml_usedchunks - 1
		     && buf->b_ml.ml_line_count - line <= 1)
	{
	    /*
	     * We are in the last chunk and it is cheap to crate a new one
	     * after this. Do it now to avoid the loop above later on
	     */
	    curchnk = buf->b_ml.ml_chunksize + curix + 1;
	    buf->b_ml.ml_usedchunks++;
	    if (line == buf->b_ml.ml_line_count)
	    {
		curchnk->mlcs_numlines = 0;
		curchnk->mlcs_totalsize = 0;
	    }
	    else
	    {
		/*
		 * Line is just prior to last, move count for last
		 * This is the common case  when loading a new file
		 */
		hp = ml_find_line(buf, buf->b_ml.ml_line_count, ML_FIND);
		if (hp == NULL)
		{
		    buf->b_ml.ml_usedchunks = -1;
		    return;
		}
		dp = (DATA_BL *)(hp->bh_data);
		if (dp->db_line_count == 1)
		    rest = dp->db_txt_end - dp->db_txt_start;
		else
		    rest =
			((dp->db_index[dp->db_line_count - 2]) & DB_INDEX_MASK)
			- dp->db_txt_start;
		curchnk->mlcs_totalsize = rest;
		curchnk->mlcs_numlines = 1;
		curchnk[-1].mlcs_totalsize -= rest;
		curchnk[-1].mlcs_numlines -= 1;
	    }
	}
    }
    else if (updtype == ML_CHNK_DELLINE)
    {
	curchnk->mlcs_numlines--;
	ml_upd_lastbuf = NULL;   // Force recalc of curix & curline
	if (curix < (buf->b_ml.ml_usedchunks - 1)
		&& (curchnk->mlcs_numlines + curchnk[1].mlcs_numlines)
		   <= MLCS_MINL)
	{
	    curix++;
	    curchnk = buf->b_ml.ml_chunksize + curix;
	}
	else if (curix == 0 && curchnk->mlcs_numlines <= 0)
	{
	    buf->b_ml.ml_usedchunks--;
	    mch_memmove(buf->b_ml.ml_chunksize, buf->b_ml.ml_chunksize + 1,
			buf->b_ml.ml_usedchunks * sizeof(chunksize_T));
	    return;
	}
	else if (curix == 0 || (curchnk->mlcs_numlines > 10
		    && (curchnk->mlcs_numlines + curchnk[-1].mlcs_numlines)
		       > MLCS_MINL))
	{
	    return;
	}

	// Collapse chunks
	curchnk[-1].mlcs_numlines += curchnk->mlcs_numlines;
	curchnk[-1].mlcs_totalsize += curchnk->mlcs_totalsize;
	buf->b_ml.ml_usedchunks--;
	if (curix < buf->b_ml.ml_usedchunks)
	{
	    mch_memmove(buf->b_ml.ml_chunksize + curix,
			buf->b_ml.ml_chunksize + curix + 1,
			(buf->b_ml.ml_usedchunks - curix) *
			sizeof(chunksize_T));
	}
	return;
    }
    ml_upd_lastbuf = buf;
    ml_upd_lastline = line;
    ml_upd_lastcurline = curline;
    ml_upd_lastcurix = curix;
}

/*
 * Find offset for line or line with offset.
 * Find line with offset if "lnum" is 0; return remaining offset in offp
 * Find offset of line if "lnum" > 0
 * return -1 if information is not available
 */
    long
ml_find_line_or_offset(buf_T *buf, linenr_T lnum, long *offp)
{
    linenr_T	curline;
    int		curix;
    long	size;
    bhdr_T	*hp;
    DATA_BL	*dp;
    int		count;		// number of entries in block
    int		idx;
    int		start_idx;
    int		text_end;
    long	offset;
    int		len;
    int		ffdos = (get_fileformat(buf) == EOL_DOS);
    int		extra = 0;

    // take care of cached line first
    ml_flush_line(curbuf);

    if (buf->b_ml.ml_usedchunks == -1
	    || buf->b_ml.ml_chunksize == NULL
	    || lnum < 0)
	return -1;

    if (offp == NULL)
	offset = 0;
    else
	offset = *offp;
    if (lnum == 0 && offset <= 0)
	return 1;   // Not a "find offset" and offset 0 _must_ be in line 1
    /*
     * Find the last chunk before the one containing our line. Last chunk is
     * special because it will never qualify
     */
    curline = 1;
    curix = size = 0;
    while (curix < buf->b_ml.ml_usedchunks - 1
	    && ((lnum != 0
	     && lnum >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines)
		|| (offset != 0
	       && offset > size + buf->b_ml.ml_chunksize[curix].mlcs_totalsize
		      + ffdos * buf->b_ml.ml_chunksize[curix].mlcs_numlines)))
    {
	curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
	size += buf->b_ml.ml_chunksize[curix].mlcs_totalsize;
	if (offset && ffdos)
	    size += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
	curix++;
    }

    while ((lnum != 0 && curline < lnum) || (offset != 0 && size < offset))
    {
	if (curline > buf->b_ml.ml_line_count
		|| (hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
	    return -1;
	dp = (DATA_BL *)(hp->bh_data);
	count = (long)(buf->b_ml.ml_locked_high) -
		(long)(buf->b_ml.ml_locked_low) + 1;
	start_idx = idx = curline - buf->b_ml.ml_locked_low;
	if (idx == 0)  // first line in block, text at the end
	    text_end = dp->db_txt_end;
	else
	    text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
	// Compute index of last line to use in this MEMLINE
	if (lnum != 0)
	{
	    if (curline + (count - idx) >= lnum)
		idx += lnum - curline - 1;
	    else
		idx = count - 1;
	}
	else
	{
#ifdef FEAT_PROP_POPUP
	    size_t textprop_total = 0;
	    size_t textprop_size = 0;
	    char_u *l1, *l2;
#endif

	    extra = 0;
	    for (;;)
	    {
#ifdef FEAT_PROP_POPUP
		if (buf->b_has_textprop)
		{
		    // compensate for the extra bytes taken by textprops
		    l1 = (char_u *)dp + ((dp->db_index[idx]) & DB_INDEX_MASK);
		    l2 = (char_u *)dp + (idx == 0 ? dp->db_txt_end
				  : ((dp->db_index[idx - 1]) & DB_INDEX_MASK));
		    textprop_size = (l2 - l1) - (STRLEN(l1) + 1);
		}
#endif
		if (!(offset >= size
			+ text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK)
#ifdef FEAT_PROP_POPUP
			- (long)(textprop_total + textprop_size)
#endif
			+ ffdos))
		    break;

		if (ffdos)
		    size++;
#ifdef FEAT_PROP_POPUP
		textprop_total += textprop_size;
#endif
		if (idx == count - 1)
		{
		    extra = 1;
		    break;
		}
		idx++;
	    }
	}
#ifdef FEAT_PROP_POPUP
	if (buf->b_has_textprop)
	{
	    int i;

	    // cannot use the db_index pointer, need to get the actual text
	    // lengths.
	    len = 0;
	    for (i = start_idx; i <= idx; ++i)
		len += (int)STRLEN((char_u *)dp
				    + ((dp->db_index[i]) & DB_INDEX_MASK)) + 1;
	}
	else
#endif
	    len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
	size += len;
	if (offset != 0 && size >= offset)
	{
	    if (size + ffdos == offset)
		*offp = 0;
	    else if (idx == start_idx)
		*offp = offset - size + len;
	    else
		*offp = offset - size + len
		     - (text_end - ((dp->db_index[idx - 1]) & DB_INDEX_MASK));
	    curline += idx - start_idx + extra;
	    if (curline > buf->b_ml.ml_line_count)
		return -1;	// exactly one byte beyond the end
	    return curline;
	}
	curline = buf->b_ml.ml_locked_high + 1;
    }

    if (lnum != 0)
    {
	// Count extra CR characters.
	if (ffdos)
	    size += lnum - 1;

	// Don't count the last line break if 'noeol' and ('bin' or
	// 'nofixeol').
	if ((!buf->b_p_fixeol || buf->b_p_bin) && !buf->b_p_eol
					   && lnum > buf->b_ml.ml_line_count)
	    size -= ffdos + 1;
    }

    return size;
}

/*
 * Goto byte in buffer with offset 'cnt'.
 */
    void
goto_byte(long cnt)
{
    long	boff = cnt;
    linenr_T	lnum;

    ml_flush_line(curbuf);	// cached line may be dirty
    setpcmark();
    if (boff)
	--boff;
    lnum = ml_find_line_or_offset(curbuf, (linenr_T)0, &boff);
    if (lnum < 1)	// past the end
    {
	curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
	curwin->w_curswant = MAXCOL;
	coladvance((colnr_T)MAXCOL);
    }
    else
    {
	curwin->w_cursor.lnum = lnum;
	curwin->w_cursor.col = (colnr_T)boff;
	curwin->w_cursor.coladd = 0;
	curwin->w_set_curswant = TRUE;
    }
    check_cursor();

    // Make sure the cursor is on the first byte of a multi-byte char.
    if (has_mbyte)
	mb_adjust_cursor();
}
#endif
