136f805083db7110261813c2b8c4fc821fd0f248
[platform/upstream/vim.git] / src / memline.c
1 /* vi:set ts=8 sts=4 sw=4:
2  *
3  * VIM - Vi IMproved    by Bram Moolenaar
4  *
5  * Do ":help uganda"  in Vim to read copying and usage conditions.
6  * Do ":help credits" in Vim to see a list of people who contributed.
7  * See README.txt for an overview of the Vim source code.
8  */
9
10 /* for debugging */
11 /* #define CHECK(c, s)  if (c) EMSG(s) */
12 #define CHECK(c, s)
13
14 /*
15  * memline.c: Contains the functions for appending, deleting and changing the
16  * text lines. The memfile functions are used to store the information in
17  * blocks of memory, backed up by a file. The structure of the information is
18  * a tree.  The root of the tree is a pointer block. The leaves of the tree
19  * are data blocks. In between may be several layers of pointer blocks,
20  * forming branches.
21  *
22  * Three types of blocks are used:
23  * - Block nr 0 contains information for recovery
24  * - Pointer blocks contain list of pointers to other blocks.
25  * - Data blocks contain the actual text.
26  *
27  * Block nr 0 contains the block0 structure (see below).
28  *
29  * Block nr 1 is the first pointer block. It is the root of the tree.
30  * Other pointer blocks are branches.
31  *
32  *  If a line is too big to fit in a single page, the block containing that
33  *  line is made big enough to hold the line. It may span several pages.
34  *  Otherwise all blocks are one page.
35  *
36  *  A data block that was filled when starting to edit a file and was not
37  *  changed since then, can have a negative block number. This means that it
38  *  has not yet been assigned a place in the file. When recovering, the lines
39  *  in this data block can be read from the original file. When the block is
40  *  changed (lines appended/deleted/changed) or when it is flushed it gets a
41  *  positive number. Use mf_trans_del() to get the new number, before calling
42  *  mf_get().
43  */
44
45 #if defined(MSDOS) || defined(WIN16) || defined(WIN32) || defined(_WIN64)
46 # include "vimio.h"     /* for mch_open(), must be before vim.h */
47 #endif
48
49 #include "vim.h"
50
51 #ifndef UNIX            /* it's in os_unix.h for Unix */
52 # include <time.h>
53 #endif
54
55 #if defined(SASC) || defined(__amigaos4__)
56 # include <proto/dos.h>     /* for Open() and Close() */
57 #endif
58
59 #ifdef HAVE_ERRNO_H
60 # include <errno.h>
61 #endif
62
63 typedef struct block0           ZERO_BL;    /* contents of the first block */
64 typedef struct pointer_block    PTR_BL;     /* contents of a pointer block */
65 typedef struct data_block       DATA_BL;    /* contents of a data block */
66 typedef struct pointer_entry    PTR_EN;     /* block/line-count pair */
67
68 #define DATA_ID        (('d' << 8) + 'a')   /* data block id */
69 #define PTR_ID         (('p' << 8) + 't')   /* pointer block id */
70 #define BLOCK0_ID0     'b'                  /* block 0 id 0 */
71 #define BLOCK0_ID1     '0'                  /* block 0 id 1 */
72 #define BLOCK0_ID1_C0  'c'                  /* block 0 id 1 'cm' 0 */
73 #define BLOCK0_ID1_C1  'C'                  /* block 0 id 1 'cm' 1 */
74
75 /*
76  * pointer to a block, used in a pointer block
77  */
78 struct pointer_entry
79 {
80     blocknr_T   pe_bnum;        /* block number */
81     linenr_T    pe_line_count;  /* number of lines in this branch */
82     linenr_T    pe_old_lnum;    /* lnum for this block (for recovery) */
83     int         pe_page_count;  /* number of pages in block pe_bnum */
84 };
85
86 /*
87  * A pointer block contains a list of branches in the tree.
88  */
89 struct pointer_block
90 {
91     short_u     pb_id;          /* ID for pointer block: PTR_ID */
92     short_u     pb_count;       /* number of pointers in this block */
93     short_u     pb_count_max;   /* maximum value for pb_count */
94     PTR_EN      pb_pointer[1];  /* list of pointers to blocks (actually longer)
95                                  * followed by empty space until end of page */
96 };
97
98 /*
99  * A data block is a leaf in the tree.
100  *
101  * The text of the lines is at the end of the block. The text of the first line
102  * in the block is put at the end, the text of the second line in front of it,
103  * etc. Thus the order of the lines is the opposite of the line number.
104  */
105 struct data_block
106 {
107     short_u     db_id;          /* ID for data block: DATA_ID */
108     unsigned    db_free;        /* free space available */
109     unsigned    db_txt_start;   /* byte where text starts */
110     unsigned    db_txt_end;     /* byte just after data block */
111     linenr_T    db_line_count;  /* number of lines in this block */
112     unsigned    db_index[1];    /* index for start of line (actually bigger)
113                                  * followed by empty space upto db_txt_start
114                                  * followed by the text in the lines until
115                                  * end of page */
116 };
117
118 /*
119  * The low bits of db_index hold the actual index. The topmost bit is
120  * used for the global command to be able to mark a line.
121  * This method is not clean, but otherwise there would be at least one extra
122  * byte used for each line.
123  * The mark has to be in this place to keep it with the correct line when other
124  * lines are inserted or deleted.
125  */
126 #define DB_MARKED       ((unsigned)1 << ((sizeof(unsigned) * 8) - 1))
127 #define DB_INDEX_MASK   (~DB_MARKED)
128
129 #define INDEX_SIZE  (sizeof(unsigned))      /* size of one db_index entry */
130 #define HEADER_SIZE (sizeof(DATA_BL) - INDEX_SIZE)  /* size of data block header */
131
132 #define B0_FNAME_SIZE_ORG       900     /* what it was in older versions */
133 #define B0_FNAME_SIZE_NOCRYPT   898     /* 2 bytes used for other things */
134 #define B0_FNAME_SIZE_CRYPT     890     /* 10 bytes used for other things */
135 #define B0_UNAME_SIZE           40
136 #define B0_HNAME_SIZE           40
137 /*
138  * Restrict the numbers to 32 bits, otherwise most compilers will complain.
139  * This won't detect a 64 bit machine that only swaps a byte in the top 32
140  * bits, but that is crazy anyway.
141  */
142 #define B0_MAGIC_LONG   0x30313233L
143 #define B0_MAGIC_INT    0x20212223L
144 #define B0_MAGIC_SHORT  0x10111213L
145 #define B0_MAGIC_CHAR   0x55
146
147 /*
148  * Block zero holds all info about the swap file.
149  *
150  * NOTE: DEFINITION OF BLOCK 0 SHOULD NOT CHANGE! It would make all existing
151  * swap files unusable!
152  *
153  * If size of block0 changes anyway, adjust MIN_SWAP_PAGE_SIZE in vim.h!!
154  *
155  * This block is built up of single bytes, to make it portable across
156  * different machines. b0_magic_* is used to check the byte order and size of
157  * variables, because the rest of the swap file is not portable.
158  */
159 struct block0
160 {
161     char_u      b0_id[2];       /* id for block 0: BLOCK0_ID0 and BLOCK0_ID1,
162                                  * BLOCK0_ID1_C0, BLOCK0_ID1_C1 */
163     char_u      b0_version[10]; /* Vim version string */
164     char_u      b0_page_size[4];/* number of bytes per page */
165     char_u      b0_mtime[4];    /* last modification time of file */
166     char_u      b0_ino[4];      /* inode of b0_fname */
167     char_u      b0_pid[4];      /* process id of creator (or 0) */
168     char_u      b0_uname[B0_UNAME_SIZE]; /* name of user (uid if no name) */
169     char_u      b0_hname[B0_HNAME_SIZE]; /* host name (if it has a name) */
170     char_u      b0_fname[B0_FNAME_SIZE_ORG]; /* name of file being edited */
171     long        b0_magic_long;  /* check for byte order of long */
172     int         b0_magic_int;   /* check for byte order of int */
173     short       b0_magic_short; /* check for byte order of short */
174     char_u      b0_magic_char;  /* check for last char */
175 };
176
177 /*
178  * Note: b0_dirty and b0_flags are put at the end of the file name.  For very
179  * long file names in older versions of Vim they are invalid.
180  * The 'fileencoding' comes before b0_flags, with a NUL in front.  But only
181  * when there is room, for very long file names it's omitted.
182  */
183 #define B0_DIRTY        0x55
184 #define b0_dirty        b0_fname[B0_FNAME_SIZE_ORG - 1]
185
186 /*
187  * The b0_flags field is new in Vim 7.0.
188  */
189 #define b0_flags        b0_fname[B0_FNAME_SIZE_ORG - 2]
190
191 /*
192  * Crypt seed goes here, 8 bytes.  New in Vim 7.3.
193  * Without encryption these bytes may be used for 'fenc'.
194  */
195 #define b0_seed         b0_fname[B0_FNAME_SIZE_ORG - 2 - MF_SEED_LEN]
196
197 /* The lowest two bits contain the fileformat.  Zero means it's not set
198  * (compatible with Vim 6.x), otherwise it's EOL_UNIX + 1, EOL_DOS + 1 or
199  * EOL_MAC + 1. */
200 #define B0_FF_MASK      3
201
202 /* Swap file is in directory of edited file.  Used to find the file from
203  * different mount points. */
204 #define B0_SAME_DIR     4
205
206 /* The 'fileencoding' is at the end of b0_fname[], with a NUL in front of it.
207  * When empty there is only the NUL. */
208 #define B0_HAS_FENC     8
209
210 #define STACK_INCR      5       /* nr of entries added to ml_stack at a time */
211
212 /*
213  * The line number where the first mark may be is remembered.
214  * If it is 0 there are no marks at all.
215  * (always used for the current buffer only, no buffer change possible while
216  * executing a global command).
217  */
218 static linenr_T lowest_marked = 0;
219
220 /*
221  * arguments for ml_find_line()
222  */
223 #define ML_DELETE       0x11        /* delete line */
224 #define ML_INSERT       0x12        /* insert line */
225 #define ML_FIND         0x13        /* just find the line */
226 #define ML_FLUSH        0x02        /* flush locked block */
227 #define ML_SIMPLE(x)    (x & 0x10)  /* DEL, INS or FIND */
228
229 /* argument for ml_upd_block0() */
230 typedef enum {
231       UB_FNAME = 0      /* update timestamp and filename */
232     , UB_SAME_DIR       /* update the B0_SAME_DIR flag */
233     , UB_CRYPT          /* update crypt key */
234 } upd_block0_T;
235
236 #ifdef FEAT_CRYPT
237 static void ml_set_b0_crypt __ARGS((buf_T *buf, ZERO_BL *b0p));
238 #endif
239 static int ml_check_b0_id __ARGS((ZERO_BL *b0p));
240 static void ml_upd_block0 __ARGS((buf_T *buf, upd_block0_T what));
241 static void set_b0_fname __ARGS((ZERO_BL *, buf_T *buf));
242 static void set_b0_dir_flag __ARGS((ZERO_BL *b0p, buf_T *buf));
243 #ifdef FEAT_MBYTE
244 static void add_b0_fenc __ARGS((ZERO_BL *b0p, buf_T *buf));
245 #endif
246 static time_t swapfile_info __ARGS((char_u *));
247 static int recov_file_names __ARGS((char_u **, char_u *, int prepend_dot));
248 static int ml_append_int __ARGS((buf_T *, linenr_T, char_u *, colnr_T, int, int));
249 static int ml_delete_int __ARGS((buf_T *, linenr_T, int));
250 static char_u *findswapname __ARGS((buf_T *, char_u **, char_u *));
251 static void ml_flush_line __ARGS((buf_T *));
252 static bhdr_T *ml_new_data __ARGS((memfile_T *, int, int));
253 static bhdr_T *ml_new_ptr __ARGS((memfile_T *));
254 static bhdr_T *ml_find_line __ARGS((buf_T *, linenr_T, int));
255 static int ml_add_stack __ARGS((buf_T *));
256 static void ml_lineadd __ARGS((buf_T *, int));
257 static int b0_magic_wrong __ARGS((ZERO_BL *));
258 #ifdef CHECK_INODE
259 static int fnamecmp_ino __ARGS((char_u *, char_u *, long));
260 #endif
261 static void long_to_char __ARGS((long, char_u *));
262 static long char_to_long __ARGS((char_u *));
263 #if defined(UNIX) || defined(WIN3264)
264 static char_u *make_percent_swname __ARGS((char_u *dir, char_u *name));
265 #endif
266 #ifdef FEAT_CRYPT
267 static void ml_crypt_prepare __ARGS((memfile_T *mfp, off_t offset, int reading));
268 #endif
269 #ifdef FEAT_BYTEOFF
270 static void ml_updatechunk __ARGS((buf_T *buf, long line, long len, int updtype));
271 #endif
272
273 /*
274  * Open a new memline for "buf".
275  *
276  * Return FAIL for failure, OK otherwise.
277  */
278     int
279 ml_open(buf)
280     buf_T       *buf;
281 {
282     memfile_T   *mfp;
283     bhdr_T      *hp = NULL;
284     ZERO_BL     *b0p;
285     PTR_BL      *pp;
286     DATA_BL     *dp;
287
288     /*
289      * init fields in memline struct
290      */
291     buf->b_ml.ml_stack_size = 0; /* no stack yet */
292     buf->b_ml.ml_stack = NULL;  /* no stack yet */
293     buf->b_ml.ml_stack_top = 0; /* nothing in the stack */
294     buf->b_ml.ml_locked = NULL; /* no cached block */
295     buf->b_ml.ml_line_lnum = 0; /* no cached line */
296 #ifdef FEAT_BYTEOFF
297     buf->b_ml.ml_chunksize = NULL;
298 #endif
299
300     /*
301      * When 'updatecount' is non-zero swap file may be opened later.
302      */
303     if (p_uc && buf->b_p_swf)
304         buf->b_may_swap = TRUE;
305     else
306         buf->b_may_swap = FALSE;
307
308     /*
309      * Open the memfile.  No swap file is created yet.
310      */
311     mfp = mf_open(NULL, 0);
312     if (mfp == NULL)
313         goto error;
314
315     buf->b_ml.ml_mfp = mfp;
316 #ifdef FEAT_CRYPT
317     mfp->mf_buffer = buf;
318 #endif
319     buf->b_ml.ml_flags = ML_EMPTY;
320     buf->b_ml.ml_line_count = 1;
321 #ifdef FEAT_LINEBREAK
322     curwin->w_nrwidth_line_count = 0;
323 #endif
324
325 #if defined(MSDOS) && !defined(DJGPP)
326     /* for 16 bit MS-DOS create a swapfile now, because we run out of
327      * memory very quickly */
328     if (p_uc != 0)
329         ml_open_file(buf);
330 #endif
331
332 /*
333  * fill block0 struct and write page 0
334  */
335     if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
336         goto error;
337     if (hp->bh_bnum != 0)
338     {
339         EMSG(_("E298: Didn't get block nr 0?"));
340         goto error;
341     }
342     b0p = (ZERO_BL *)(hp->bh_data);
343
344     b0p->b0_id[0] = BLOCK0_ID0;
345     b0p->b0_id[1] = BLOCK0_ID1;
346     b0p->b0_magic_long = (long)B0_MAGIC_LONG;
347     b0p->b0_magic_int = (int)B0_MAGIC_INT;
348     b0p->b0_magic_short = (short)B0_MAGIC_SHORT;
349     b0p->b0_magic_char = B0_MAGIC_CHAR;
350     STRNCPY(b0p->b0_version, "VIM ", 4);
351     STRNCPY(b0p->b0_version + 4, Version, 6);
352     long_to_char((long)mfp->mf_page_size, b0p->b0_page_size);
353
354 #ifdef FEAT_SPELL
355     if (!buf->b_spell)
356 #endif
357     {
358         b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
359         b0p->b0_flags = get_fileformat(buf) + 1;
360         set_b0_fname(b0p, buf);
361         (void)get_user_name(b0p->b0_uname, B0_UNAME_SIZE);
362         b0p->b0_uname[B0_UNAME_SIZE - 1] = NUL;
363         mch_get_host_name(b0p->b0_hname, B0_HNAME_SIZE);
364         b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL;
365         long_to_char(mch_get_pid(), b0p->b0_pid);
366 #ifdef FEAT_CRYPT
367         if (*buf->b_p_key != NUL)
368             ml_set_b0_crypt(buf, b0p);
369 #endif
370     }
371
372     /*
373      * Always sync block number 0 to disk, so we can check the file name in
374      * the swap file in findswapname(). Don't do this for a help files or
375      * a spell buffer though.
376      * Only works when there's a swapfile, otherwise it's done when the file
377      * is created.
378      */
379     mf_put(mfp, hp, TRUE, FALSE);
380     if (!buf->b_help && !B_SPELL(buf))
381         (void)mf_sync(mfp, 0);
382
383     /*
384      * Fill in root pointer block and write page 1.
385      */
386     if ((hp = ml_new_ptr(mfp)) == NULL)
387         goto error;
388     if (hp->bh_bnum != 1)
389     {
390         EMSG(_("E298: Didn't get block nr 1?"));
391         goto error;
392     }
393     pp = (PTR_BL *)(hp->bh_data);
394     pp->pb_count = 1;
395     pp->pb_pointer[0].pe_bnum = 2;
396     pp->pb_pointer[0].pe_page_count = 1;
397     pp->pb_pointer[0].pe_old_lnum = 1;
398     pp->pb_pointer[0].pe_line_count = 1;    /* line count after insertion */
399     mf_put(mfp, hp, TRUE, FALSE);
400
401     /*
402      * Allocate first data block and create an empty line 1.
403      */
404     if ((hp = ml_new_data(mfp, FALSE, 1)) == NULL)
405         goto error;
406     if (hp->bh_bnum != 2)
407     {
408         EMSG(_("E298: Didn't get block nr 2?"));
409         goto error;
410     }
411
412     dp = (DATA_BL *)(hp->bh_data);
413     dp->db_index[0] = --dp->db_txt_start;       /* at end of block */
414     dp->db_free -= 1 + INDEX_SIZE;
415     dp->db_line_count = 1;
416     *((char_u *)dp + dp->db_txt_start) = NUL;   /* empty line */
417
418     return OK;
419
420 error:
421     if (mfp != NULL)
422     {
423         if (hp)
424             mf_put(mfp, hp, FALSE, FALSE);
425         mf_close(mfp, TRUE);        /* will also free(mfp->mf_fname) */
426     }
427     buf->b_ml.ml_mfp = NULL;
428     return FAIL;
429 }
430
431 #if defined(FEAT_CRYPT) || defined(PROTO)
432 /*
433  * Prepare encryption for "buf" with block 0 "b0p".
434  */
435     static void
436 ml_set_b0_crypt(buf, b0p)
437     buf_T       *buf;
438     ZERO_BL     *b0p;
439 {
440     if (*buf->b_p_key == NUL)
441         b0p->b0_id[1] = BLOCK0_ID1;
442     else
443     {
444         if (get_crypt_method(buf) == 0)
445             b0p->b0_id[1] = BLOCK0_ID1_C0;
446         else
447         {
448             b0p->b0_id[1] = BLOCK0_ID1_C1;
449             /* Generate a seed and store it in block 0 and in the memfile. */
450             sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0);
451             mch_memmove(buf->b_ml.ml_mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
452         }
453     }
454 }
455
456 /*
457  * Called after the crypt key or 'cryptmethod' was changed for "buf".
458  * Will apply this to the swapfile.
459  * "old_key" is the previous key.  It is equal to buf->b_p_key when
460  * 'cryptmethod' is changed.
461  * "old_cm" is the previous 'cryptmethod'.  It is equal to the current
462  * 'cryptmethod' when 'key' is changed.
463  */
464     void
465 ml_set_crypt_key(buf, old_key, old_cm)
466     buf_T       *buf;
467     char_u      *old_key;
468     int         old_cm;
469 {
470     memfile_T   *mfp = buf->b_ml.ml_mfp;
471     bhdr_T      *hp;
472     int         page_count;
473     int         idx;
474     long        error;
475     infoptr_T   *ip;
476     PTR_BL      *pp;
477     DATA_BL     *dp;
478     blocknr_T   bnum;
479     int         top;
480
481     if (mfp == NULL)
482         return;  /* no memfile yet, nothing to do */
483
484     /* Set the key, method and seed to be used for reading, these must be the
485      * old values. */
486     mfp->mf_old_key = old_key;
487     mfp->mf_old_cm = old_cm;
488     if (old_cm > 0)
489         mch_memmove(mfp->mf_old_seed, mfp->mf_seed, MF_SEED_LEN);
490
491     /* Update block 0 with the crypt flag and may set a new seed. */
492     ml_upd_block0(buf, UB_CRYPT);
493
494     if (mfp->mf_infile_count > 2)
495     {
496         /*
497          * Need to read back all data blocks from disk, decrypt them with the
498          * old key/method and mark them to be written. The algorithm is
499          * similar to what happens in ml_recover(), but we skip negative block
500          * numbers.
501          */
502         ml_flush_line(buf);                 /* flush buffered line */
503         (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */
504
505         hp = NULL;
506         bnum = 1;               /* start with block 1 */
507         page_count = 1;         /* which is 1 page */
508         idx = 0;                /* start with first index in block 1 */
509         error = 0;
510         buf->b_ml.ml_stack_top = 0;
511         vim_free(buf->b_ml.ml_stack);
512         buf->b_ml.ml_stack = NULL;
513         buf->b_ml.ml_stack_size = 0;    /* no stack yet */
514
515         for ( ; !got_int; line_breakcheck())
516         {
517             if (hp != NULL)
518                 mf_put(mfp, hp, FALSE, FALSE);  /* release previous block */
519
520             /* get the block (pointer or data) */
521             if ((hp = mf_get(mfp, (blocknr_T)bnum, page_count)) == NULL)
522             {
523                 if (bnum == 1)
524                     break;
525                 ++error;
526             }
527             else
528             {
529                 pp = (PTR_BL *)(hp->bh_data);
530                 if (pp->pb_id == PTR_ID)        /* it is a pointer block */
531                 {
532                     if (pp->pb_count == 0)
533                     {
534                         /* empty block? */
535                         ++error;
536                     }
537                     else if (idx < (int)pp->pb_count)   /* go a block deeper */
538                     {
539                         if (pp->pb_pointer[idx].pe_bnum < 0)
540                         {
541                             /* Skip data block with negative block number. */
542                             ++idx;    /* get same block again for next index */
543                             continue;
544                         }
545
546                         /* going one block deeper in the tree, new entry in
547                          * stack */
548                         if ((top = ml_add_stack(buf)) < 0)
549                         {
550                             ++error;
551                             break;                  /* out of memory */
552                         }
553                         ip = &(buf->b_ml.ml_stack[top]);
554                         ip->ip_bnum = bnum;
555                         ip->ip_index = idx;
556
557                         bnum = pp->pb_pointer[idx].pe_bnum;
558                         page_count = pp->pb_pointer[idx].pe_page_count;
559                         continue;
560                     }
561                 }
562                 else        /* not a pointer block */
563                 {
564                     dp = (DATA_BL *)(hp->bh_data);
565                     if (dp->db_id != DATA_ID)   /* block id wrong */
566                         ++error;
567                     else
568                     {
569                         /* It is a data block, need to write it back to disk. */
570                         mf_put(mfp, hp, TRUE, FALSE);
571                         hp = NULL;
572                     }
573                 }
574             }
575
576             if (buf->b_ml.ml_stack_top == 0)    /* finished */
577                 break;
578
579             /* go one block up in the tree */
580             ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]);
581             bnum = ip->ip_bnum;
582             idx = ip->ip_index + 1;         /* go to next index */
583             page_count = 1;
584         }
585     }
586
587     mfp->mf_old_key = NULL;
588 }
589 #endif
590
591 /*
592  * ml_setname() is called when the file name of "buf" has been changed.
593  * It may rename the swap file.
594  */
595     void
596 ml_setname(buf)
597     buf_T       *buf;
598 {
599     int         success = FALSE;
600     memfile_T   *mfp;
601     char_u      *fname;
602     char_u      *dirp;
603 #if defined(MSDOS) || defined(MSWIN)
604     char_u      *p;
605 #endif
606
607     mfp = buf->b_ml.ml_mfp;
608     if (mfp->mf_fd < 0)             /* there is no swap file yet */
609     {
610         /*
611          * When 'updatecount' is 0 and 'noswapfile' there is no swap file.
612          * For help files we will make a swap file now.
613          */
614         if (p_uc != 0)
615             ml_open_file(buf);      /* create a swap file */
616         return;
617     }
618
619     /*
620      * Try all directories in the 'directory' option.
621      */
622     dirp = p_dir;
623     for (;;)
624     {
625         if (*dirp == NUL)           /* tried all directories, fail */
626             break;
627         fname = findswapname(buf, &dirp, mfp->mf_fname);
628                                                     /* alloc's fname */
629         if (fname == NULL)          /* no file name found for this dir */
630             continue;
631
632 #if defined(MSDOS) || defined(MSWIN)
633         /*
634          * Set full pathname for swap file now, because a ":!cd dir" may
635          * change directory without us knowing it.
636          */
637         p = FullName_save(fname, FALSE);
638         vim_free(fname);
639         fname = p;
640         if (fname == NULL)
641             continue;
642 #endif
643         /* if the file name is the same we don't have to do anything */
644         if (fnamecmp(fname, mfp->mf_fname) == 0)
645         {
646             vim_free(fname);
647             success = TRUE;
648             break;
649         }
650         /* need to close the swap file before renaming */
651         if (mfp->mf_fd >= 0)
652         {
653             close(mfp->mf_fd);
654             mfp->mf_fd = -1;
655         }
656
657         /* try to rename the swap file */
658         if (vim_rename(mfp->mf_fname, fname) == 0)
659         {
660             success = TRUE;
661             vim_free(mfp->mf_fname);
662             mfp->mf_fname = fname;
663             vim_free(mfp->mf_ffname);
664 #if defined(MSDOS) || defined(MSWIN)
665             mfp->mf_ffname = NULL;  /* mf_fname is full pathname already */
666 #else
667             mf_set_ffname(mfp);
668 #endif
669             ml_upd_block0(buf, UB_SAME_DIR);
670             break;
671         }
672         vim_free(fname);            /* this fname didn't work, try another */
673     }
674
675     if (mfp->mf_fd == -1)           /* need to (re)open the swap file */
676     {
677         mfp->mf_fd = mch_open((char *)mfp->mf_fname, O_RDWR | O_EXTRA, 0);
678         if (mfp->mf_fd < 0)
679         {
680             /* could not (re)open the swap file, what can we do???? */
681             EMSG(_("E301: Oops, lost the swap file!!!"));
682             return;
683         }
684 #ifdef HAVE_FD_CLOEXEC
685         {
686             int fdflags = fcntl(mfp->mf_fd, F_GETFD);
687             if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0)
688                 fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC);
689         }
690 #endif
691     }
692     if (!success)
693         EMSG(_("E302: Could not rename swap file"));
694 }
695
696 /*
697  * Open a file for the memfile for all buffers that are not readonly or have
698  * been modified.
699  * Used when 'updatecount' changes from zero to non-zero.
700  */
701     void
702 ml_open_files()
703 {
704     buf_T       *buf;
705
706     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
707         if (!buf->b_p_ro || buf->b_changed)
708             ml_open_file(buf);
709 }
710
711 /*
712  * Open a swap file for an existing memfile, if there is no swap file yet.
713  * If we are unable to find a file name, mf_fname will be NULL
714  * and the memfile will be in memory only (no recovery possible).
715  */
716     void
717 ml_open_file(buf)
718     buf_T       *buf;
719 {
720     memfile_T   *mfp;
721     char_u      *fname;
722     char_u      *dirp;
723
724     mfp = buf->b_ml.ml_mfp;
725     if (mfp == NULL || mfp->mf_fd >= 0 || !buf->b_p_swf)
726         return;         /* nothing to do */
727
728 #ifdef FEAT_SPELL
729     /* For a spell buffer use a temp file name. */
730     if (buf->b_spell)
731     {
732         fname = vim_tempname('s');
733         if (fname != NULL)
734             (void)mf_open_file(mfp, fname);     /* consumes fname! */
735         buf->b_may_swap = FALSE;
736         return;
737     }
738 #endif
739
740     /*
741      * Try all directories in 'directory' option.
742      */
743     dirp = p_dir;
744     for (;;)
745     {
746         if (*dirp == NUL)
747             break;
748         /* There is a small chance that between choosing the swap file name
749          * and creating it, another Vim creates the file.  In that case the
750          * creation will fail and we will use another directory. */
751         fname = findswapname(buf, &dirp, NULL); /* allocates fname */
752         if (fname == NULL)
753             continue;
754         if (mf_open_file(mfp, fname) == OK)     /* consumes fname! */
755         {
756 #if defined(MSDOS) || defined(MSWIN) || defined(RISCOS)
757             /*
758              * set full pathname for swap file now, because a ":!cd dir" may
759              * change directory without us knowing it.
760              */
761             mf_fullname(mfp);
762 #endif
763             ml_upd_block0(buf, UB_SAME_DIR);
764
765             /* Flush block zero, so others can read it */
766             if (mf_sync(mfp, MFS_ZERO) == OK)
767             {
768                 /* Mark all blocks that should be in the swapfile as dirty.
769                  * Needed for when the 'swapfile' option was reset, so that
770                  * the swap file was deleted, and then on again. */
771                 mf_set_dirty(mfp);
772                 break;
773             }
774             /* Writing block 0 failed: close the file and try another dir */
775             mf_close_file(buf, FALSE);
776         }
777     }
778
779     if (mfp->mf_fname == NULL)          /* Failed! */
780     {
781         need_wait_return = TRUE;        /* call wait_return later */
782         ++no_wait_return;
783         (void)EMSG2(_("E303: Unable to open swap file for \"%s\", recovery impossible"),
784                     buf_spname(buf) != NULL
785                         ? (char_u *)buf_spname(buf)
786                         : buf->b_fname);
787         --no_wait_return;
788     }
789
790     /* don't try to open a swap file again */
791     buf->b_may_swap = FALSE;
792 }
793
794 /*
795  * If still need to create a swap file, and starting to edit a not-readonly
796  * file, or reading into an existing buffer, create a swap file now.
797  */
798     void
799 check_need_swap(newfile)
800     int     newfile;            /* reading file into new buffer */
801 {
802     if (curbuf->b_may_swap && (!curbuf->b_p_ro || !newfile))
803         ml_open_file(curbuf);
804 }
805
806 /*
807  * Close memline for buffer 'buf'.
808  * If 'del_file' is TRUE, delete the swap file
809  */
810     void
811 ml_close(buf, del_file)
812     buf_T       *buf;
813     int         del_file;
814 {
815     if (buf->b_ml.ml_mfp == NULL)               /* not open */
816         return;
817     mf_close(buf->b_ml.ml_mfp, del_file);       /* close the .swp file */
818     if (buf->b_ml.ml_line_lnum != 0 && (buf->b_ml.ml_flags & ML_LINE_DIRTY))
819         vim_free(buf->b_ml.ml_line_ptr);
820     vim_free(buf->b_ml.ml_stack);
821 #ifdef FEAT_BYTEOFF
822     vim_free(buf->b_ml.ml_chunksize);
823     buf->b_ml.ml_chunksize = NULL;
824 #endif
825     buf->b_ml.ml_mfp = NULL;
826
827     /* Reset the "recovered" flag, give the ATTENTION prompt the next time
828      * this buffer is loaded. */
829     buf->b_flags &= ~BF_RECOVERED;
830 }
831
832 /*
833  * Close all existing memlines and memfiles.
834  * Only used when exiting.
835  * When 'del_file' is TRUE, delete the memfiles.
836  * But don't delete files that were ":preserve"d when we are POSIX compatible.
837  */
838     void
839 ml_close_all(del_file)
840     int         del_file;
841 {
842     buf_T       *buf;
843
844     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
845         ml_close(buf, del_file && ((buf->b_flags & BF_PRESERVED) == 0
846                                  || vim_strchr(p_cpo, CPO_PRESERVE) == NULL));
847 #ifdef TEMPDIRNAMES
848     vim_deltempdir();       /* delete created temp directory */
849 #endif
850 }
851
852 /*
853  * Close all memfiles for not modified buffers.
854  * Only use just before exiting!
855  */
856     void
857 ml_close_notmod()
858 {
859     buf_T       *buf;
860
861     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
862         if (!bufIsChanged(buf))
863             ml_close(buf, TRUE);    /* close all not-modified buffers */
864 }
865
866 /*
867  * Update the timestamp in the .swp file.
868  * Used when the file has been written.
869  */
870     void
871 ml_timestamp(buf)
872     buf_T       *buf;
873 {
874     ml_upd_block0(buf, UB_FNAME);
875 }
876
877 /*
878  * Return FAIL when the ID of "b0p" is wrong.
879  */
880     static int
881 ml_check_b0_id(b0p)
882     ZERO_BL     *b0p;
883 {
884     if (b0p->b0_id[0] != BLOCK0_ID0
885             || (b0p->b0_id[1] != BLOCK0_ID1
886                 && b0p->b0_id[1] != BLOCK0_ID1_C0
887                 && b0p->b0_id[1] != BLOCK0_ID1_C1)
888             )
889         return FAIL;
890     return OK;
891 }
892
893 /*
894  * Update the timestamp or the B0_SAME_DIR flag of the .swp file.
895  */
896     static void
897 ml_upd_block0(buf, what)
898     buf_T       *buf;
899     upd_block0_T what;
900 {
901     memfile_T   *mfp;
902     bhdr_T      *hp;
903     ZERO_BL     *b0p;
904
905     mfp = buf->b_ml.ml_mfp;
906     if (mfp == NULL || (hp = mf_get(mfp, (blocknr_T)0, 1)) == NULL)
907         return;
908     b0p = (ZERO_BL *)(hp->bh_data);
909     if (ml_check_b0_id(b0p) == FAIL)
910         EMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
911     else
912     {
913         if (what == UB_FNAME)
914             set_b0_fname(b0p, buf);
915 #ifdef FEAT_CRYPT
916         else if (what == UB_CRYPT)
917             ml_set_b0_crypt(buf, b0p);
918 #endif
919         else /* what == UB_SAME_DIR */
920             set_b0_dir_flag(b0p, buf);
921     }
922     mf_put(mfp, hp, TRUE, FALSE);
923 }
924
925 /*
926  * Write file name and timestamp into block 0 of a swap file.
927  * Also set buf->b_mtime.
928  * Don't use NameBuff[]!!!
929  */
930     static void
931 set_b0_fname(b0p, buf)
932     ZERO_BL     *b0p;
933     buf_T       *buf;
934 {
935     struct stat st;
936
937     if (buf->b_ffname == NULL)
938         b0p->b0_fname[0] = NUL;
939     else
940     {
941 #if defined(MSDOS) || defined(MSWIN) || defined(AMIGA) || defined(RISCOS)
942         /* Systems that cannot translate "~user" back into a path: copy the
943          * file name unmodified.  Do use slashes instead of backslashes for
944          * portability. */
945         vim_strncpy(b0p->b0_fname, buf->b_ffname, B0_FNAME_SIZE_CRYPT - 1);
946 # ifdef BACKSLASH_IN_FILENAME
947         forward_slash(b0p->b0_fname);
948 # endif
949 #else
950         size_t  flen, ulen;
951         char_u  uname[B0_UNAME_SIZE];
952
953         /*
954          * For a file under the home directory of the current user, we try to
955          * replace the home directory path with "~user". This helps when
956          * editing the same file on different machines over a network.
957          * First replace home dir path with "~/" with home_replace().
958          * Then insert the user name to get "~user/".
959          */
960         home_replace(NULL, buf->b_ffname, b0p->b0_fname,
961                                                    B0_FNAME_SIZE_CRYPT, TRUE);
962         if (b0p->b0_fname[0] == '~')
963         {
964             flen = STRLEN(b0p->b0_fname);
965             /* If there is no user name or it is too long, don't use "~/" */
966             if (get_user_name(uname, B0_UNAME_SIZE) == FAIL
967                    || (ulen = STRLEN(uname)) + flen > B0_FNAME_SIZE_CRYPT - 1)
968                 vim_strncpy(b0p->b0_fname, buf->b_ffname,
969                                                      B0_FNAME_SIZE_CRYPT - 1);
970             else
971             {
972                 mch_memmove(b0p->b0_fname + ulen + 1, b0p->b0_fname + 1, flen);
973                 mch_memmove(b0p->b0_fname + 1, uname, ulen);
974             }
975         }
976 #endif
977         if (mch_stat((char *)buf->b_ffname, &st) >= 0)
978         {
979             long_to_char((long)st.st_mtime, b0p->b0_mtime);
980 #ifdef CHECK_INODE
981             long_to_char((long)st.st_ino, b0p->b0_ino);
982 #endif
983             buf_store_time(buf, &st, buf->b_ffname);
984             buf->b_mtime_read = buf->b_mtime;
985         }
986         else
987         {
988             long_to_char(0L, b0p->b0_mtime);
989 #ifdef CHECK_INODE
990             long_to_char(0L, b0p->b0_ino);
991 #endif
992             buf->b_mtime = 0;
993             buf->b_mtime_read = 0;
994             buf->b_orig_size = 0;
995             buf->b_orig_mode = 0;
996         }
997     }
998
999 #ifdef FEAT_MBYTE
1000     /* Also add the 'fileencoding' if there is room. */
1001     add_b0_fenc(b0p, curbuf);
1002 #endif
1003 }
1004
1005 /*
1006  * Update the B0_SAME_DIR flag of the swap file.  It's set if the file and the
1007  * swapfile for "buf" are in the same directory.
1008  * This is fail safe: if we are not sure the directories are equal the flag is
1009  * not set.
1010  */
1011     static void
1012 set_b0_dir_flag(b0p, buf)
1013     ZERO_BL     *b0p;
1014     buf_T       *buf;
1015 {
1016     if (same_directory(buf->b_ml.ml_mfp->mf_fname, buf->b_ffname))
1017         b0p->b0_flags |= B0_SAME_DIR;
1018     else
1019         b0p->b0_flags &= ~B0_SAME_DIR;
1020 }
1021
1022 #ifdef FEAT_MBYTE
1023 /*
1024  * When there is room, add the 'fileencoding' to block zero.
1025  */
1026     static void
1027 add_b0_fenc(b0p, buf)
1028     ZERO_BL     *b0p;
1029     buf_T       *buf;
1030 {
1031     int         n;
1032     int         size = B0_FNAME_SIZE_NOCRYPT;
1033
1034 # ifdef FEAT_CRYPT
1035     /* Without encryption use the same offset as in Vim 7.2 to be compatible.
1036      * With encryption it's OK to move elsewhere, the swap file is not
1037      * compatible anyway. */
1038     if (*buf->b_p_key != NUL)
1039         size = B0_FNAME_SIZE_CRYPT;
1040 # endif
1041
1042     n = (int)STRLEN(buf->b_p_fenc);
1043     if ((int)STRLEN(b0p->b0_fname) + n + 1 > size)
1044         b0p->b0_flags &= ~B0_HAS_FENC;
1045     else
1046     {
1047         mch_memmove((char *)b0p->b0_fname + size - n,
1048                                             (char *)buf->b_p_fenc, (size_t)n);
1049         *(b0p->b0_fname + size - n - 1) = NUL;
1050         b0p->b0_flags |= B0_HAS_FENC;
1051     }
1052 }
1053 #endif
1054
1055
1056 /*
1057  * Try to recover curbuf from the .swp file.
1058  */
1059     void
1060 ml_recover()
1061 {
1062     buf_T       *buf = NULL;
1063     memfile_T   *mfp = NULL;
1064     char_u      *fname;
1065     char_u      *fname_used = NULL;
1066     bhdr_T      *hp = NULL;
1067     ZERO_BL     *b0p;
1068     int         b0_ff;
1069     char_u      *b0_fenc = NULL;
1070 #ifdef FEAT_CRYPT
1071     int         b0_cm = -1;
1072 #endif
1073     PTR_BL      *pp;
1074     DATA_BL     *dp;
1075     infoptr_T   *ip;
1076     blocknr_T   bnum;
1077     int         page_count;
1078     struct stat org_stat, swp_stat;
1079     int         len;
1080     int         directly;
1081     linenr_T    lnum;
1082     char_u      *p;
1083     int         i;
1084     long        error;
1085     int         cannot_open;
1086     linenr_T    line_count;
1087     int         has_error;
1088     int         idx;
1089     int         top;
1090     int         txt_start;
1091     off_t       size;
1092     int         called_from_main;
1093     int         serious_error = TRUE;
1094     long        mtime;
1095     int         attr;
1096     int         orig_file_status = NOTDONE;
1097
1098     recoverymode = TRUE;
1099     called_from_main = (curbuf->b_ml.ml_mfp == NULL);
1100     attr = hl_attr(HLF_E);
1101
1102     /*
1103      * If the file name ends in ".s[uvw][a-z]" we assume this is the swap file.
1104      * Otherwise a search is done to find the swap file(s).
1105      */
1106     fname = curbuf->b_fname;
1107     if (fname == NULL)              /* When there is no file name */
1108         fname = (char_u *)"";
1109     len = (int)STRLEN(fname);
1110     if (len >= 4 &&
1111 #if defined(VMS) || defined(RISCOS)
1112             STRNICMP(fname + len - 4, "_s" , 2)
1113 #else
1114             STRNICMP(fname + len - 4, ".s" , 2)
1115 #endif
1116                 == 0
1117                 && vim_strchr((char_u *)"UVWuvw", fname[len - 2]) != NULL
1118                 && ASCII_ISALPHA(fname[len - 1]))
1119     {
1120         directly = TRUE;
1121         fname_used = vim_strsave(fname); /* make a copy for mf_open() */
1122     }
1123     else
1124     {
1125         directly = FALSE;
1126
1127         /* count the number of matching swap files */
1128         len = recover_names(fname, FALSE, 0, NULL);
1129         if (len == 0)               /* no swap files found */
1130         {
1131             EMSG2(_("E305: No swap file found for %s"), fname);
1132             goto theend;
1133         }
1134         if (len == 1)               /* one swap file found, use it */
1135             i = 1;
1136         else                        /* several swap files found, choose */
1137         {
1138             /* list the names of the swap files */
1139             (void)recover_names(fname, TRUE, 0, NULL);
1140             msg_putchar('\n');
1141             MSG_PUTS(_("Enter number of swap file to use (0 to quit): "));
1142             i = get_number(FALSE, NULL);
1143             if (i < 1 || i > len)
1144                 goto theend;
1145         }
1146         /* get the swap file name that will be used */
1147         (void)recover_names(fname, FALSE, i, &fname_used);
1148     }
1149     if (fname_used == NULL)
1150         goto theend;                    /* out of memory */
1151
1152     /* When called from main() still need to initialize storage structure */
1153     if (called_from_main && ml_open(curbuf) == FAIL)
1154         getout(1);
1155
1156     /*
1157      * Allocate a buffer structure for the swap file that is used for recovery.
1158      * Only the memline and crypt information in it are really used.
1159      */
1160     buf = (buf_T *)alloc((unsigned)sizeof(buf_T));
1161     if (buf == NULL)
1162         goto theend;
1163
1164     /*
1165      * init fields in memline struct
1166      */
1167     buf->b_ml.ml_stack_size = 0;        /* no stack yet */
1168     buf->b_ml.ml_stack = NULL;          /* no stack yet */
1169     buf->b_ml.ml_stack_top = 0;         /* nothing in the stack */
1170     buf->b_ml.ml_line_lnum = 0;         /* no cached line */
1171     buf->b_ml.ml_locked = NULL;         /* no locked block */
1172     buf->b_ml.ml_flags = 0;
1173 #ifdef FEAT_CRYPT
1174     buf->b_p_key = empty_option;
1175     buf->b_p_cm = empty_option;
1176 #endif
1177
1178     /*
1179      * open the memfile from the old swap file
1180      */
1181     p = vim_strsave(fname_used); /* save "fname_used" for the message:
1182                                     mf_open() will consume "fname_used"! */
1183     mfp = mf_open(fname_used, O_RDONLY);
1184     fname_used = p;
1185     if (mfp == NULL || mfp->mf_fd < 0)
1186     {
1187         if (fname_used != NULL)
1188             EMSG2(_("E306: Cannot open %s"), fname_used);
1189         goto theend;
1190     }
1191     buf->b_ml.ml_mfp = mfp;
1192 #ifdef FEAT_CRYPT
1193     mfp->mf_buffer = buf;
1194 #endif
1195
1196     /*
1197      * The page size set in mf_open() might be different from the page size
1198      * used in the swap file, we must get it from block 0.  But to read block
1199      * 0 we need a page size.  Use the minimal size for block 0 here, it will
1200      * be set to the real value below.
1201      */
1202     mfp->mf_page_size = MIN_SWAP_PAGE_SIZE;
1203
1204     /*
1205      * try to read block 0
1206      */
1207     if ((hp = mf_get(mfp, (blocknr_T)0, 1)) == NULL)
1208     {
1209         msg_start();
1210         MSG_PUTS_ATTR(_("Unable to read block 0 from "), attr | MSG_HIST);
1211         msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
1212         MSG_PUTS_ATTR(_("\nMaybe no changes were made or Vim did not update the swap file."),
1213                 attr | MSG_HIST);
1214         msg_end();
1215         goto theend;
1216     }
1217     b0p = (ZERO_BL *)(hp->bh_data);
1218     if (STRNCMP(b0p->b0_version, "VIM 3.0", 7) == 0)
1219     {
1220         msg_start();
1221         msg_outtrans_attr(mfp->mf_fname, MSG_HIST);
1222         MSG_PUTS_ATTR(_(" cannot be used with this version of Vim.\n"),
1223                                                                     MSG_HIST);
1224         MSG_PUTS_ATTR(_("Use Vim version 3.0.\n"), MSG_HIST);
1225         msg_end();
1226         goto theend;
1227     }
1228     if (ml_check_b0_id(b0p) == FAIL)
1229     {
1230         EMSG2(_("E307: %s does not look like a Vim swap file"), mfp->mf_fname);
1231         goto theend;
1232     }
1233     if (b0_magic_wrong(b0p))
1234     {
1235         msg_start();
1236         msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
1237 #if defined(MSDOS) || defined(MSWIN)
1238         if (STRNCMP(b0p->b0_hname, "PC ", 3) == 0)
1239             MSG_PUTS_ATTR(_(" cannot be used with this version of Vim.\n"),
1240                                                              attr | MSG_HIST);
1241         else
1242 #endif
1243             MSG_PUTS_ATTR(_(" cannot be used on this computer.\n"),
1244                                                              attr | MSG_HIST);
1245         MSG_PUTS_ATTR(_("The file was created on "), attr | MSG_HIST);
1246         /* avoid going past the end of a corrupted hostname */
1247         b0p->b0_fname[0] = NUL;
1248         MSG_PUTS_ATTR(b0p->b0_hname, attr | MSG_HIST);
1249         MSG_PUTS_ATTR(_(",\nor the file has been damaged."), attr | MSG_HIST);
1250         msg_end();
1251         goto theend;
1252     }
1253
1254 #ifdef FEAT_CRYPT
1255     if (b0p->b0_id[1] == BLOCK0_ID1_C0)
1256         b0_cm = 0;
1257     else if (b0p->b0_id[1] == BLOCK0_ID1_C1)
1258     {
1259         b0_cm = 1;
1260         mch_memmove(mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
1261     }
1262     set_crypt_method(buf, b0_cm);
1263 #else
1264     if (b0p->b0_id[1] != BLOCK0_ID1)
1265     {
1266         EMSG2(_("E833: %s is encrypted and this version of Vim does not support encryption"), mfp->mf_fname);
1267         goto theend;
1268     }
1269 #endif
1270
1271     /*
1272      * If we guessed the wrong page size, we have to recalculate the
1273      * highest block number in the file.
1274      */
1275     if (mfp->mf_page_size != (unsigned)char_to_long(b0p->b0_page_size))
1276     {
1277         unsigned previous_page_size = mfp->mf_page_size;
1278
1279         mf_new_page_size(mfp, (unsigned)char_to_long(b0p->b0_page_size));
1280         if (mfp->mf_page_size < previous_page_size)
1281         {
1282             msg_start();
1283             msg_outtrans_attr(mfp->mf_fname, attr | MSG_HIST);
1284             MSG_PUTS_ATTR(_(" has been damaged (page size is smaller than minimum value).\n"),
1285                         attr | MSG_HIST);
1286             msg_end();
1287             goto theend;
1288         }
1289         if ((size = lseek(mfp->mf_fd, (off_t)0L, SEEK_END)) <= 0)
1290             mfp->mf_blocknr_max = 0;        /* no file or empty file */
1291         else
1292             mfp->mf_blocknr_max = (blocknr_T)(size / mfp->mf_page_size);
1293         mfp->mf_infile_count = mfp->mf_blocknr_max;
1294
1295         /* need to reallocate the memory used to store the data */
1296         p = alloc(mfp->mf_page_size);
1297         if (p == NULL)
1298             goto theend;
1299         mch_memmove(p, hp->bh_data, previous_page_size);
1300         vim_free(hp->bh_data);
1301         hp->bh_data = p;
1302         b0p = (ZERO_BL *)(hp->bh_data);
1303     }
1304
1305     /*
1306      * If .swp file name given directly, use name from swap file for buffer.
1307      */
1308     if (directly)
1309     {
1310         expand_env(b0p->b0_fname, NameBuff, MAXPATHL);
1311         if (setfname(curbuf, NameBuff, NULL, TRUE) == FAIL)
1312             goto theend;
1313     }
1314
1315     home_replace(NULL, mfp->mf_fname, NameBuff, MAXPATHL, TRUE);
1316     smsg((char_u *)_("Using swap file \"%s\""), NameBuff);
1317
1318     if (buf_spname(curbuf) != NULL)
1319         STRCPY(NameBuff, buf_spname(curbuf));
1320     else
1321         home_replace(NULL, curbuf->b_ffname, NameBuff, MAXPATHL, TRUE);
1322     smsg((char_u *)_("Original file \"%s\""), NameBuff);
1323     msg_putchar('\n');
1324
1325     /*
1326      * check date of swap file and original file
1327      */
1328     mtime = char_to_long(b0p->b0_mtime);
1329     if (curbuf->b_ffname != NULL
1330             && mch_stat((char *)curbuf->b_ffname, &org_stat) != -1
1331             && ((mch_stat((char *)mfp->mf_fname, &swp_stat) != -1
1332                     && org_stat.st_mtime > swp_stat.st_mtime)
1333                 || org_stat.st_mtime != mtime))
1334     {
1335         EMSG(_("E308: Warning: Original file may have been changed"));
1336     }
1337     out_flush();
1338
1339     /* Get the 'fileformat' and 'fileencoding' from block zero. */
1340     b0_ff = (b0p->b0_flags & B0_FF_MASK);
1341     if (b0p->b0_flags & B0_HAS_FENC)
1342     {
1343         int fnsize = B0_FNAME_SIZE_NOCRYPT;
1344
1345 #ifdef FEAT_CRYPT
1346         /* Use the same size as in add_b0_fenc(). */
1347         if (b0p->b0_id[1] != BLOCK0_ID1)
1348             fnsize = B0_FNAME_SIZE_CRYPT;
1349 #endif
1350         for (p = b0p->b0_fname + fnsize; p > b0p->b0_fname && p[-1] != NUL; --p)
1351             ;
1352         b0_fenc = vim_strnsave(p, (int)(b0p->b0_fname + fnsize - p));
1353     }
1354
1355     mf_put(mfp, hp, FALSE, FALSE);      /* release block 0 */
1356     hp = NULL;
1357
1358     /*
1359      * Now that we are sure that the file is going to be recovered, clear the
1360      * contents of the current buffer.
1361      */
1362     while (!(curbuf->b_ml.ml_flags & ML_EMPTY))
1363         ml_delete((linenr_T)1, FALSE);
1364
1365     /*
1366      * Try reading the original file to obtain the values of 'fileformat',
1367      * 'fileencoding', etc.  Ignore errors.  The text itself is not used.
1368      * When the file is encrypted the user is asked to enter the key.
1369      */
1370     if (curbuf->b_ffname != NULL)
1371         orig_file_status = readfile(curbuf->b_ffname, NULL, (linenr_T)0,
1372                               (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW);
1373
1374 #ifdef FEAT_CRYPT
1375     if (b0_cm >= 0)
1376     {
1377         /* Need to ask the user for the crypt key.  If this fails we continue
1378          * without a key, will probably get garbage text. */
1379         if (*curbuf->b_p_key != NUL)
1380         {
1381             smsg((char_u *)_("Swap file is encrypted: \"%s\""), fname_used);
1382             MSG_PUTS(_("\nIf you entered a new crypt key but did not write the text file,"));
1383             MSG_PUTS(_("\nenter the new crypt key."));
1384             MSG_PUTS(_("\nIf you wrote the text file after changing the crypt key press enter"));
1385             MSG_PUTS(_("\nto use the same key for text file and swap file"));
1386         }
1387         else
1388             smsg((char_u *)_(need_key_msg), fname_used);
1389         buf->b_p_key = get_crypt_key(FALSE, FALSE);
1390         if (buf->b_p_key == NULL)
1391             buf->b_p_key = curbuf->b_p_key;
1392         else if (*buf->b_p_key == NUL)
1393         {
1394             vim_free(buf->b_p_key);
1395             buf->b_p_key = curbuf->b_p_key;
1396         }
1397         if (buf->b_p_key == NULL)
1398             buf->b_p_key = empty_option;
1399     }
1400 #endif
1401
1402     /* Use the 'fileformat' and 'fileencoding' as stored in the swap file. */
1403     if (b0_ff != 0)
1404         set_fileformat(b0_ff - 1, OPT_LOCAL);
1405     if (b0_fenc != NULL)
1406     {
1407         set_option_value((char_u *)"fenc", 0L, b0_fenc, OPT_LOCAL);
1408         vim_free(b0_fenc);
1409     }
1410     unchanged(curbuf, TRUE);
1411
1412     bnum = 1;           /* start with block 1 */
1413     page_count = 1;     /* which is 1 page */
1414     lnum = 0;           /* append after line 0 in curbuf */
1415     line_count = 0;
1416     idx = 0;            /* start with first index in block 1 */
1417     error = 0;
1418     buf->b_ml.ml_stack_top = 0;
1419     buf->b_ml.ml_stack = NULL;
1420     buf->b_ml.ml_stack_size = 0;        /* no stack yet */
1421
1422     if (curbuf->b_ffname == NULL)
1423         cannot_open = TRUE;
1424     else
1425         cannot_open = FALSE;
1426
1427     serious_error = FALSE;
1428     for ( ; !got_int; line_breakcheck())
1429     {
1430         if (hp != NULL)
1431             mf_put(mfp, hp, FALSE, FALSE);      /* release previous block */
1432
1433         /*
1434          * get block
1435          */
1436         if ((hp = mf_get(mfp, (blocknr_T)bnum, page_count)) == NULL)
1437         {
1438             if (bnum == 1)
1439             {
1440                 EMSG2(_("E309: Unable to read block 1 from %s"), mfp->mf_fname);
1441                 goto theend;
1442             }
1443             ++error;
1444             ml_append(lnum++, (char_u *)_("???MANY LINES MISSING"),
1445                                                             (colnr_T)0, TRUE);
1446         }
1447         else            /* there is a block */
1448         {
1449             pp = (PTR_BL *)(hp->bh_data);
1450             if (pp->pb_id == PTR_ID)            /* it is a pointer block */
1451             {
1452                 /* check line count when using pointer block first time */
1453                 if (idx == 0 && line_count != 0)
1454                 {
1455                     for (i = 0; i < (int)pp->pb_count; ++i)
1456                         line_count -= pp->pb_pointer[i].pe_line_count;
1457                     if (line_count != 0)
1458                     {
1459                         ++error;
1460                         ml_append(lnum++, (char_u *)_("???LINE COUNT WRONG"),
1461                                                             (colnr_T)0, TRUE);
1462                     }
1463                 }
1464
1465                 if (pp->pb_count == 0)
1466                 {
1467                     ml_append(lnum++, (char_u *)_("???EMPTY BLOCK"),
1468                                                             (colnr_T)0, TRUE);
1469                     ++error;
1470                 }
1471                 else if (idx < (int)pp->pb_count)       /* go a block deeper */
1472                 {
1473                     if (pp->pb_pointer[idx].pe_bnum < 0)
1474                     {
1475                         /*
1476                          * Data block with negative block number.
1477                          * Try to read lines from the original file.
1478                          * This is slow, but it works.
1479                          */
1480                         if (!cannot_open)
1481                         {
1482                             line_count = pp->pb_pointer[idx].pe_line_count;
1483                             if (readfile(curbuf->b_ffname, NULL, lnum,
1484                                         pp->pb_pointer[idx].pe_old_lnum - 1,
1485                                         line_count, NULL, 0) == FAIL)
1486                                 cannot_open = TRUE;
1487                             else
1488                                 lnum += line_count;
1489                         }
1490                         if (cannot_open)
1491                         {
1492                             ++error;
1493                             ml_append(lnum++, (char_u *)_("???LINES MISSING"),
1494                                                             (colnr_T)0, TRUE);
1495                         }
1496                         ++idx;      /* get same block again for next index */
1497                         continue;
1498                     }
1499
1500                     /*
1501                      * going one block deeper in the tree
1502                      */
1503                     if ((top = ml_add_stack(buf)) < 0)  /* new entry in stack */
1504                     {
1505                         ++error;
1506                         break;              /* out of memory */
1507                     }
1508                     ip = &(buf->b_ml.ml_stack[top]);
1509                     ip->ip_bnum = bnum;
1510                     ip->ip_index = idx;
1511
1512                     bnum = pp->pb_pointer[idx].pe_bnum;
1513                     line_count = pp->pb_pointer[idx].pe_line_count;
1514                     page_count = pp->pb_pointer[idx].pe_page_count;
1515                     continue;
1516                 }
1517             }
1518             else            /* not a pointer block */
1519             {
1520                 dp = (DATA_BL *)(hp->bh_data);
1521                 if (dp->db_id != DATA_ID)       /* block id wrong */
1522                 {
1523                     if (bnum == 1)
1524                     {
1525                         EMSG2(_("E310: Block 1 ID wrong (%s not a .swp file?)"),
1526                                                                mfp->mf_fname);
1527                         goto theend;
1528                     }
1529                     ++error;
1530                     ml_append(lnum++, (char_u *)_("???BLOCK MISSING"),
1531                                                             (colnr_T)0, TRUE);
1532                 }
1533                 else
1534                 {
1535                     /*
1536                      * it is a data block
1537                      * Append all the lines in this block
1538                      */
1539                     has_error = FALSE;
1540                         /*
1541                          * check length of block
1542                          * if wrong, use length in pointer block
1543                          */
1544                     if (page_count * mfp->mf_page_size != dp->db_txt_end)
1545                     {
1546                         ml_append(lnum++, (char_u *)_("??? from here until ???END lines may be messed up"),
1547                                                             (colnr_T)0, TRUE);
1548                         ++error;
1549                         has_error = TRUE;
1550                         dp->db_txt_end = page_count * mfp->mf_page_size;
1551                     }
1552
1553                         /* make sure there is a NUL at the end of the block */
1554                     *((char_u *)dp + dp->db_txt_end - 1) = NUL;
1555
1556                         /*
1557                          * check number of lines in block
1558                          * if wrong, use count in data block
1559                          */
1560                     if (line_count != dp->db_line_count)
1561                     {
1562                         ml_append(lnum++, (char_u *)_("??? from here until ???END lines may have been inserted/deleted"),
1563                                                             (colnr_T)0, TRUE);
1564                         ++error;
1565                         has_error = TRUE;
1566                     }
1567
1568                     for (i = 0; i < dp->db_line_count; ++i)
1569                     {
1570                         txt_start = (dp->db_index[i] & DB_INDEX_MASK);
1571                         if (txt_start <= (int)HEADER_SIZE
1572                                           || txt_start >= (int)dp->db_txt_end)
1573                         {
1574                             p = (char_u *)"???";
1575                             ++error;
1576                         }
1577                         else
1578                             p = (char_u *)dp + txt_start;
1579                         ml_append(lnum++, p, (colnr_T)0, TRUE);
1580                     }
1581                     if (has_error)
1582                         ml_append(lnum++, (char_u *)_("???END"),
1583                                                             (colnr_T)0, TRUE);
1584                 }
1585             }
1586         }
1587
1588         if (buf->b_ml.ml_stack_top == 0)        /* finished */
1589             break;
1590
1591         /*
1592          * go one block up in the tree
1593          */
1594         ip = &(buf->b_ml.ml_stack[--(buf->b_ml.ml_stack_top)]);
1595         bnum = ip->ip_bnum;
1596         idx = ip->ip_index + 1;     /* go to next index */
1597         page_count = 1;
1598     }
1599
1600     /*
1601      * Compare the buffer contents with the original file.  When they differ
1602      * set the 'modified' flag.
1603      * Lines 1 - lnum are the new contents.
1604      * Lines lnum + 1 to ml_line_count are the original contents.
1605      * Line ml_line_count + 1 in the dummy empty line.
1606      */
1607     if (orig_file_status != OK || curbuf->b_ml.ml_line_count != lnum * 2 + 1)
1608     {
1609         /* Recovering an empty file results in two lines and the first line is
1610          * empty.  Don't set the modified flag then. */
1611         if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL))
1612         {
1613             changed_int();
1614             ++curbuf->b_changedtick;
1615         }
1616     }
1617     else
1618     {
1619         for (idx = 1; idx <= lnum; ++idx)
1620         {
1621             /* Need to copy one line, fetching the other one may flush it. */
1622             p = vim_strsave(ml_get(idx));
1623             i = STRCMP(p, ml_get(idx + lnum));
1624             vim_free(p);
1625             if (i != 0)
1626             {
1627                 changed_int();
1628                 ++curbuf->b_changedtick;
1629                 break;
1630             }
1631         }
1632     }
1633
1634     /*
1635      * Delete the lines from the original file and the dummy line from the
1636      * empty buffer.  These will now be after the last line in the buffer.
1637      */
1638     while (curbuf->b_ml.ml_line_count > lnum
1639                                        && !(curbuf->b_ml.ml_flags & ML_EMPTY))
1640         ml_delete(curbuf->b_ml.ml_line_count, FALSE);
1641     curbuf->b_flags |= BF_RECOVERED;
1642
1643     recoverymode = FALSE;
1644     if (got_int)
1645         EMSG(_("E311: Recovery Interrupted"));
1646     else if (error)
1647     {
1648         ++no_wait_return;
1649         MSG(">>>>>>>>>>>>>");
1650         EMSG(_("E312: Errors detected while recovering; look for lines starting with ???"));
1651         --no_wait_return;
1652         MSG(_("See \":help E312\" for more information."));
1653         MSG(">>>>>>>>>>>>>");
1654     }
1655     else
1656     {
1657         if (curbuf->b_changed)
1658         {
1659             MSG(_("Recovery completed. You should check if everything is OK."));
1660             MSG_PUTS(_("\n(You might want to write out this file under another name\n"));
1661             MSG_PUTS(_("and run diff with the original file to check for changes)"));
1662         }
1663         else
1664             MSG(_("Recovery completed. Buffer contents equals file contents."));
1665         MSG_PUTS(_("\nYou may want to delete the .swp file now.\n\n"));
1666         cmdline_row = msg_row;
1667     }
1668 #ifdef FEAT_CRYPT
1669     if (*buf->b_p_key != NUL && STRCMP(curbuf->b_p_key, buf->b_p_key) != 0)
1670     {
1671         MSG_PUTS(_("Using crypt key from swap file for the text file.\n"));
1672         set_option_value((char_u *)"key", 0L, buf->b_p_key, OPT_LOCAL);
1673     }
1674 #endif
1675     redraw_curbuf_later(NOT_VALID);
1676
1677 theend:
1678     vim_free(fname_used);
1679     recoverymode = FALSE;
1680     if (mfp != NULL)
1681     {
1682         if (hp != NULL)
1683             mf_put(mfp, hp, FALSE, FALSE);
1684         mf_close(mfp, FALSE);       /* will also vim_free(mfp->mf_fname) */
1685     }
1686     if (buf != NULL)
1687     {
1688 #ifdef FEAT_CRYPT
1689         if (buf->b_p_key != curbuf->b_p_key)
1690             free_string_option(buf->b_p_key);
1691         free_string_option(buf->b_p_cm);
1692 #endif
1693         vim_free(buf->b_ml.ml_stack);
1694         vim_free(buf);
1695     }
1696     if (serious_error && called_from_main)
1697         ml_close(curbuf, TRUE);
1698 #ifdef FEAT_AUTOCMD
1699     else
1700     {
1701         apply_autocmds(EVENT_BUFREADPOST, NULL, curbuf->b_fname, FALSE, curbuf);
1702         apply_autocmds(EVENT_BUFWINENTER, NULL, curbuf->b_fname, FALSE, curbuf);
1703     }
1704 #endif
1705     return;
1706 }
1707
1708 /*
1709  * Find the names of swap files in current directory and the directory given
1710  * with the 'directory' option.
1711  *
1712  * Used to:
1713  * - list the swap files for "vim -r"
1714  * - count the number of swap files when recovering
1715  * - list the swap files when recovering
1716  * - find the name of the n'th swap file when recovering
1717  */
1718     int
1719 recover_names(fname, list, nr, fname_out)
1720     char_u      *fname;         /* base for swap file name */
1721     int         list;           /* when TRUE, list the swap file names */
1722     int         nr;             /* when non-zero, return nr'th swap file name */
1723     char_u      **fname_out;    /* result when "nr" > 0 */
1724 {
1725     int         num_names;
1726     char_u      *(names[6]);
1727     char_u      *tail;
1728     char_u      *p;
1729     int         num_files;
1730     int         file_count = 0;
1731     char_u      **files;
1732     int         i;
1733     char_u      *dirp;
1734     char_u      *dir_name;
1735     char_u      *fname_res = NULL;
1736 #ifdef HAVE_READLINK
1737     char_u      fname_buf[MAXPATHL];
1738 #endif
1739
1740     if (fname != NULL)
1741     {
1742 #ifdef HAVE_READLINK
1743         /* Expand symlink in the file name, because the swap file is created
1744          * with the actual file instead of with the symlink. */
1745         if (resolve_symlink(fname, fname_buf) == OK)
1746             fname_res = fname_buf;
1747         else
1748 #endif
1749             fname_res = fname;
1750     }
1751
1752     if (list)
1753     {
1754         /* use msg() to start the scrolling properly */
1755         msg((char_u *)_("Swap files found:"));
1756         msg_putchar('\n');
1757     }
1758
1759     /*
1760      * Do the loop for every directory in 'directory'.
1761      * First allocate some memory to put the directory name in.
1762      */
1763     dir_name = alloc((unsigned)STRLEN(p_dir) + 1);
1764     dirp = p_dir;
1765     while (dir_name != NULL && *dirp)
1766     {
1767         /*
1768          * Isolate a directory name from *dirp and put it in dir_name (we know
1769          * it is large enough, so use 31000 for length).
1770          * Advance dirp to next directory name.
1771          */
1772         (void)copy_option_part(&dirp, dir_name, 31000, ",");
1773
1774         if (dir_name[0] == '.' && dir_name[1] == NUL)   /* check current dir */
1775         {
1776             if (fname == NULL)
1777             {
1778 #ifdef VMS
1779                 names[0] = vim_strsave((char_u *)"*_sw%");
1780 #else
1781 # ifdef RISCOS
1782                 names[0] = vim_strsave((char_u *)"*_sw#");
1783 # else
1784                 names[0] = vim_strsave((char_u *)"*.sw?");
1785 # endif
1786 #endif
1787 #if defined(UNIX) || defined(WIN3264)
1788                 /* For Unix names starting with a dot are special.  MS-Windows
1789                  * supports this too, on some file systems. */
1790                 names[1] = vim_strsave((char_u *)".*.sw?");
1791                 names[2] = vim_strsave((char_u *)".sw?");
1792                 num_names = 3;
1793 #else
1794 # ifdef VMS
1795                 names[1] = vim_strsave((char_u *)".*_sw%");
1796                 num_names = 2;
1797 # else
1798                 num_names = 1;
1799 # endif
1800 #endif
1801             }
1802             else
1803                 num_names = recov_file_names(names, fname_res, TRUE);
1804         }
1805         else                        /* check directory dir_name */
1806         {
1807             if (fname == NULL)
1808             {
1809 #ifdef VMS
1810                 names[0] = concat_fnames(dir_name, (char_u *)"*_sw%", TRUE);
1811 #else
1812 # ifdef RISCOS
1813                 names[0] = concat_fnames(dir_name, (char_u *)"*_sw#", TRUE);
1814 # else
1815                 names[0] = concat_fnames(dir_name, (char_u *)"*.sw?", TRUE);
1816 # endif
1817 #endif
1818 #if defined(UNIX) || defined(WIN3264)
1819                 /* For Unix names starting with a dot are special.  MS-Windows
1820                  * supports this too, on some file systems. */
1821                 names[1] = concat_fnames(dir_name, (char_u *)".*.sw?", TRUE);
1822                 names[2] = concat_fnames(dir_name, (char_u *)".sw?", TRUE);
1823                 num_names = 3;
1824 #else
1825 # ifdef VMS
1826                 names[1] = concat_fnames(dir_name, (char_u *)".*_sw%", TRUE);
1827                 num_names = 2;
1828 # else
1829                 num_names = 1;
1830 # endif
1831 #endif
1832             }
1833             else
1834             {
1835 #if defined(UNIX) || defined(WIN3264)
1836                 p = dir_name + STRLEN(dir_name);
1837                 if (after_pathsep(dir_name, p) && p[-1] == p[-2])
1838                 {
1839                     /* Ends with '//', Use Full path for swap name */
1840                     tail = make_percent_swname(dir_name, fname_res);
1841                 }
1842                 else
1843 #endif
1844                 {
1845                     tail = gettail(fname_res);
1846                     tail = concat_fnames(dir_name, tail, TRUE);
1847                 }
1848                 if (tail == NULL)
1849                     num_names = 0;
1850                 else
1851                 {
1852                     num_names = recov_file_names(names, tail, FALSE);
1853                     vim_free(tail);
1854                 }
1855             }
1856         }
1857
1858             /* check for out-of-memory */
1859         for (i = 0; i < num_names; ++i)
1860         {
1861             if (names[i] == NULL)
1862             {
1863                 for (i = 0; i < num_names; ++i)
1864                     vim_free(names[i]);
1865                 num_names = 0;
1866             }
1867         }
1868         if (num_names == 0)
1869             num_files = 0;
1870         else if (expand_wildcards(num_names, names, &num_files, &files,
1871                                         EW_KEEPALL|EW_FILE|EW_SILENT) == FAIL)
1872             num_files = 0;
1873
1874         /*
1875          * When no swap file found, wildcard expansion might have failed (e.g.
1876          * not able to execute the shell).
1877          * Try finding a swap file by simply adding ".swp" to the file name.
1878          */
1879         if (*dirp == NUL && file_count + num_files == 0 && fname != NULL)
1880         {
1881             struct stat     st;
1882             char_u          *swapname;
1883
1884             swapname = modname(fname_res,
1885 #if defined(VMS) || defined(RISCOS)
1886                                (char_u *)"_swp", FALSE
1887 #else
1888                                (char_u *)".swp", TRUE
1889 #endif
1890                               );
1891             if (swapname != NULL)
1892             {
1893                 if (mch_stat((char *)swapname, &st) != -1)          /* It exists! */
1894                 {
1895                     files = (char_u **)alloc((unsigned)sizeof(char_u *));
1896                     if (files != NULL)
1897                     {
1898                         files[0] = swapname;
1899                         swapname = NULL;
1900                         num_files = 1;
1901                     }
1902                 }
1903                 vim_free(swapname);
1904             }
1905         }
1906
1907         /*
1908          * remove swapfile name of the current buffer, it must be ignored
1909          */
1910         if (curbuf->b_ml.ml_mfp != NULL
1911                                && (p = curbuf->b_ml.ml_mfp->mf_fname) != NULL)
1912         {
1913             for (i = 0; i < num_files; ++i)
1914                 if (fullpathcmp(p, files[i], TRUE) & FPC_SAME)
1915                 {
1916                     /* Remove the name from files[i].  Move further entries
1917                      * down.  When the array becomes empty free it here, since
1918                      * FreeWild() won't be called below. */
1919                     vim_free(files[i]);
1920                     if (--num_files == 0)
1921                         vim_free(files);
1922                     else
1923                         for ( ; i < num_files; ++i)
1924                             files[i] = files[i + 1];
1925                 }
1926         }
1927         if (nr > 0)
1928         {
1929             file_count += num_files;
1930             if (nr <= file_count)
1931             {
1932                 *fname_out = vim_strsave(
1933                                       files[nr - 1 + num_files - file_count]);
1934                 dirp = (char_u *)"";                /* stop searching */
1935             }
1936         }
1937         else if (list)
1938         {
1939             if (dir_name[0] == '.' && dir_name[1] == NUL)
1940             {
1941                 if (fname == NULL)
1942                     MSG_PUTS(_("   In current directory:\n"));
1943                 else
1944                     MSG_PUTS(_("   Using specified name:\n"));
1945             }
1946             else
1947             {
1948                 MSG_PUTS(_("   In directory "));
1949                 msg_home_replace(dir_name);
1950                 MSG_PUTS(":\n");
1951             }
1952
1953             if (num_files)
1954             {
1955                 for (i = 0; i < num_files; ++i)
1956                 {
1957                     /* print the swap file name */
1958                     msg_outnum((long)++file_count);
1959                     MSG_PUTS(".    ");
1960                     msg_puts(gettail(files[i]));
1961                     msg_putchar('\n');
1962                     (void)swapfile_info(files[i]);
1963                 }
1964             }
1965             else
1966                 MSG_PUTS(_("      -- none --\n"));
1967             out_flush();
1968         }
1969         else
1970             file_count += num_files;
1971
1972         for (i = 0; i < num_names; ++i)
1973             vim_free(names[i]);
1974         if (num_files > 0)
1975             FreeWild(num_files, files);
1976     }
1977     vim_free(dir_name);
1978     return file_count;
1979 }
1980
1981 #if defined(UNIX) || defined(WIN3264)  /* Need _very_ long file names */
1982 /*
1983  * Append the full path to name with path separators made into percent
1984  * signs, to dir. An unnamed buffer is handled as "" (<currentdir>/"")
1985  */
1986     static char_u *
1987 make_percent_swname(dir, name)
1988     char_u      *dir;
1989     char_u      *name;
1990 {
1991     char_u *d, *s, *f;
1992
1993     f = fix_fname(name != NULL ? name : (char_u *) "");
1994     d = NULL;
1995     if (f != NULL)
1996     {
1997         s = alloc((unsigned)(STRLEN(f) + 1));
1998         if (s != NULL)
1999         {
2000             STRCPY(s, f);
2001             for (d = s; *d != NUL; mb_ptr_adv(d))
2002                 if (vim_ispathsep(*d))
2003                     *d = '%';
2004             d = concat_fnames(dir, s, TRUE);
2005             vim_free(s);
2006         }
2007         vim_free(f);
2008     }
2009     return d;
2010 }
2011 #endif
2012
2013 #if (defined(UNIX) || defined(__EMX__) || defined(VMS)) && (defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG))
2014 static int process_still_running;
2015 #endif
2016
2017 /*
2018  * Give information about an existing swap file.
2019  * Returns timestamp (0 when unknown).
2020  */
2021     static time_t
2022 swapfile_info(fname)
2023     char_u      *fname;
2024 {
2025     struct stat     st;
2026     int             fd;
2027     struct block0   b0;
2028     time_t          x = (time_t)0;
2029     char            *p;
2030 #ifdef UNIX
2031     char_u          uname[B0_UNAME_SIZE];
2032 #endif
2033
2034     /* print the swap file date */
2035     if (mch_stat((char *)fname, &st) != -1)
2036     {
2037 #ifdef UNIX
2038         /* print name of owner of the file */
2039         if (mch_get_uname(st.st_uid, uname, B0_UNAME_SIZE) == OK)
2040         {
2041             MSG_PUTS(_("          owned by: "));
2042             msg_outtrans(uname);
2043             MSG_PUTS(_("   dated: "));
2044         }
2045         else
2046 #endif
2047             MSG_PUTS(_("             dated: "));
2048         x = st.st_mtime;                    /* Manx C can't do &st.st_mtime */
2049         p = ctime(&x);                      /* includes '\n' */
2050         if (p == NULL)
2051             MSG_PUTS("(invalid)\n");
2052         else
2053             MSG_PUTS(p);
2054     }
2055
2056     /*
2057      * print the original file name
2058      */
2059     fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
2060     if (fd >= 0)
2061     {
2062         if (read(fd, (char *)&b0, sizeof(b0)) == sizeof(b0))
2063         {
2064             if (STRNCMP(b0.b0_version, "VIM 3.0", 7) == 0)
2065             {
2066                 MSG_PUTS(_("         [from Vim version 3.0]"));
2067             }
2068             else if (ml_check_b0_id(&b0) == FAIL)
2069             {
2070                 MSG_PUTS(_("         [does not look like a Vim swap file]"));
2071             }
2072             else
2073             {
2074                 MSG_PUTS(_("         file name: "));
2075                 if (b0.b0_fname[0] == NUL)
2076                     MSG_PUTS(_("[No Name]"));
2077                 else
2078                     msg_outtrans(b0.b0_fname);
2079
2080                 MSG_PUTS(_("\n          modified: "));
2081                 MSG_PUTS(b0.b0_dirty ? _("YES") : _("no"));
2082
2083                 if (*(b0.b0_uname) != NUL)
2084                 {
2085                     MSG_PUTS(_("\n         user name: "));
2086                     msg_outtrans(b0.b0_uname);
2087                 }
2088
2089                 if (*(b0.b0_hname) != NUL)
2090                 {
2091                     if (*(b0.b0_uname) != NUL)
2092                         MSG_PUTS(_("   host name: "));
2093                     else
2094                         MSG_PUTS(_("\n         host name: "));
2095                     msg_outtrans(b0.b0_hname);
2096                 }
2097
2098                 if (char_to_long(b0.b0_pid) != 0L)
2099                 {
2100                     MSG_PUTS(_("\n        process ID: "));
2101                     msg_outnum(char_to_long(b0.b0_pid));
2102 #if defined(UNIX) || defined(__EMX__)
2103                     /* EMX kill() not working correctly, it seems */
2104                     if (kill((pid_t)char_to_long(b0.b0_pid), 0) == 0)
2105                     {
2106                         MSG_PUTS(_(" (still running)"));
2107 # if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
2108                         process_still_running = TRUE;
2109 # endif
2110                     }
2111 #endif
2112                 }
2113
2114                 if (b0_magic_wrong(&b0))
2115                 {
2116 #if defined(MSDOS) || defined(MSWIN)
2117                     if (STRNCMP(b0.b0_hname, "PC ", 3) == 0)
2118                         MSG_PUTS(_("\n         [not usable with this version of Vim]"));
2119                     else
2120 #endif
2121                         MSG_PUTS(_("\n         [not usable on this computer]"));
2122                 }
2123             }
2124         }
2125         else
2126             MSG_PUTS(_("         [cannot be read]"));
2127         close(fd);
2128     }
2129     else
2130         MSG_PUTS(_("         [cannot be opened]"));
2131     msg_putchar('\n');
2132
2133     return x;
2134 }
2135
2136     static int
2137 recov_file_names(names, path, prepend_dot)
2138     char_u      **names;
2139     char_u      *path;
2140     int         prepend_dot;
2141 {
2142     int         num_names;
2143
2144 #ifdef SHORT_FNAME
2145     /*
2146      * (MS-DOS) always short names
2147      */
2148     names[0] = modname(path, (char_u *)".sw?", FALSE);
2149     num_names = 1;
2150 #else /* !SHORT_FNAME */
2151     /*
2152      * (Win32 and Win64) never short names, but do prepend a dot.
2153      * (Not MS-DOS or Win32 or Win64) maybe short name, maybe not: Try both.
2154      * Only use the short name if it is different.
2155      */
2156     char_u      *p;
2157     int         i;
2158 # ifndef WIN3264
2159     int     shortname = curbuf->b_shortname;
2160
2161     curbuf->b_shortname = FALSE;
2162 # endif
2163
2164     num_names = 0;
2165
2166     /*
2167      * May also add the file name with a dot prepended, for swap file in same
2168      * dir as original file.
2169      */
2170     if (prepend_dot)
2171     {
2172         names[num_names] = modname(path, (char_u *)".sw?", TRUE);
2173         if (names[num_names] == NULL)
2174             goto end;
2175         ++num_names;
2176     }
2177
2178     /*
2179      * Form the normal swap file name pattern by appending ".sw?".
2180      */
2181 #ifdef VMS
2182     names[num_names] = concat_fnames(path, (char_u *)"_sw%", FALSE);
2183 #else
2184 # ifdef RISCOS
2185     names[num_names] = concat_fnames(path, (char_u *)"_sw#", FALSE);
2186 # else
2187     names[num_names] = concat_fnames(path, (char_u *)".sw?", FALSE);
2188 # endif
2189 #endif
2190     if (names[num_names] == NULL)
2191         goto end;
2192     if (num_names >= 1)     /* check if we have the same name twice */
2193     {
2194         p = names[num_names - 1];
2195         i = (int)STRLEN(names[num_names - 1]) - (int)STRLEN(names[num_names]);
2196         if (i > 0)
2197             p += i;         /* file name has been expanded to full path */
2198
2199         if (STRCMP(p, names[num_names]) != 0)
2200             ++num_names;
2201         else
2202             vim_free(names[num_names]);
2203     }
2204     else
2205         ++num_names;
2206
2207 # ifndef WIN3264
2208     /*
2209      * Also try with 'shortname' set, in case the file is on a DOS filesystem.
2210      */
2211     curbuf->b_shortname = TRUE;
2212 #ifdef VMS
2213     names[num_names] = modname(path, (char_u *)"_sw%", FALSE);
2214 #else
2215 # ifdef RISCOS
2216     names[num_names] = modname(path, (char_u *)"_sw#", FALSE);
2217 # else
2218     names[num_names] = modname(path, (char_u *)".sw?", FALSE);
2219 # endif
2220 #endif
2221     if (names[num_names] == NULL)
2222         goto end;
2223
2224     /*
2225      * Remove the one from 'shortname', if it's the same as with 'noshortname'.
2226      */
2227     p = names[num_names];
2228     i = STRLEN(names[num_names]) - STRLEN(names[num_names - 1]);
2229     if (i > 0)
2230         p += i;         /* file name has been expanded to full path */
2231     if (STRCMP(names[num_names - 1], p) == 0)
2232         vim_free(names[num_names]);
2233     else
2234         ++num_names;
2235 # endif
2236
2237 end:
2238 # ifndef WIN3264
2239     curbuf->b_shortname = shortname;
2240 # endif
2241
2242 #endif /* !SHORT_FNAME */
2243
2244     return num_names;
2245 }
2246
2247 /*
2248  * sync all memlines
2249  *
2250  * If 'check_file' is TRUE, check if original file exists and was not changed.
2251  * If 'check_char' is TRUE, stop syncing when character becomes available, but
2252  * always sync at least one block.
2253  */
2254     void
2255 ml_sync_all(check_file, check_char)
2256     int     check_file;
2257     int     check_char;
2258 {
2259     buf_T               *buf;
2260     struct stat         st;
2261
2262     for (buf = firstbuf; buf != NULL; buf = buf->b_next)
2263     {
2264         if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
2265             continue;                       /* no file */
2266
2267         ml_flush_line(buf);                 /* flush buffered line */
2268                                             /* flush locked block */
2269         (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH);
2270         if (bufIsChanged(buf) && check_file && mf_need_trans(buf->b_ml.ml_mfp)
2271                                                      && buf->b_ffname != NULL)
2272         {
2273             /*
2274              * If the original file does not exist anymore or has been changed
2275              * call ml_preserve() to get rid of all negative numbered blocks.
2276              */
2277             if (mch_stat((char *)buf->b_ffname, &st) == -1
2278                     || st.st_mtime != buf->b_mtime_read
2279                     || st.st_size != buf->b_orig_size)
2280             {
2281                 ml_preserve(buf, FALSE);
2282                 did_check_timestamps = FALSE;
2283                 need_check_timestamps = TRUE;   /* give message later */
2284             }
2285         }
2286         if (buf->b_ml.ml_mfp->mf_dirty)
2287         {
2288             (void)mf_sync(buf->b_ml.ml_mfp, (check_char ? MFS_STOP : 0)
2289                                         | (bufIsChanged(buf) ? MFS_FLUSH : 0));
2290             if (check_char && ui_char_avail())  /* character available now */
2291                 break;
2292         }
2293     }
2294 }
2295
2296 /*
2297  * sync one buffer, including negative blocks
2298  *
2299  * after this all the blocks are in the swap file
2300  *
2301  * Used for the :preserve command and when the original file has been
2302  * changed or deleted.
2303  *
2304  * when message is TRUE the success of preserving is reported
2305  */
2306     void
2307 ml_preserve(buf, message)
2308     buf_T       *buf;
2309     int         message;
2310 {
2311     bhdr_T      *hp;
2312     linenr_T    lnum;
2313     memfile_T   *mfp = buf->b_ml.ml_mfp;
2314     int         status;
2315     int         got_int_save = got_int;
2316
2317     if (mfp == NULL || mfp->mf_fname == NULL)
2318     {
2319         if (message)
2320             EMSG(_("E313: Cannot preserve, there is no swap file"));
2321         return;
2322     }
2323
2324     /* We only want to stop when interrupted here, not when interrupted
2325      * before. */
2326     got_int = FALSE;
2327
2328     ml_flush_line(buf);                             /* flush buffered line */
2329     (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */
2330     status = mf_sync(mfp, MFS_ALL | MFS_FLUSH);
2331
2332     /* stack is invalid after mf_sync(.., MFS_ALL) */
2333     buf->b_ml.ml_stack_top = 0;
2334
2335     /*
2336      * Some of the data blocks may have been changed from negative to
2337      * positive block number. In that case the pointer blocks need to be
2338      * updated.
2339      *
2340      * We don't know in which pointer block the references are, so we visit
2341      * all data blocks until there are no more translations to be done (or
2342      * we hit the end of the file, which can only happen in case a write fails,
2343      * e.g. when file system if full).
2344      * ml_find_line() does the work by translating the negative block numbers
2345      * when getting the first line of each data block.
2346      */
2347     if (mf_need_trans(mfp) && !got_int)
2348     {
2349         lnum = 1;
2350         while (mf_need_trans(mfp) && lnum <= buf->b_ml.ml_line_count)
2351         {
2352             hp = ml_find_line(buf, lnum, ML_FIND);
2353             if (hp == NULL)
2354             {
2355                 status = FAIL;
2356                 goto theend;
2357             }
2358             CHECK(buf->b_ml.ml_locked_low != lnum, "low != lnum");
2359             lnum = buf->b_ml.ml_locked_high + 1;
2360         }
2361         (void)ml_find_line(buf, (linenr_T)0, ML_FLUSH); /* flush locked block */
2362         /* sync the updated pointer blocks */
2363         if (mf_sync(mfp, MFS_ALL | MFS_FLUSH) == FAIL)
2364             status = FAIL;
2365         buf->b_ml.ml_stack_top = 0;         /* stack is invalid now */
2366     }
2367 theend:
2368     got_int |= got_int_save;
2369
2370     if (message)
2371     {
2372         if (status == OK)
2373             MSG(_("File preserved"));
2374         else
2375             EMSG(_("E314: Preserve failed"));
2376     }
2377 }
2378
2379 /*
2380  * NOTE: The pointer returned by the ml_get_*() functions only remains valid
2381  * until the next call!
2382  *  line1 = ml_get(1);
2383  *  line2 = ml_get(2);  // line1 is now invalid!
2384  * Make a copy of the line if necessary.
2385  */
2386 /*
2387  * get a pointer to a (read-only copy of a) line
2388  *
2389  * On failure an error message is given and IObuff is returned (to avoid
2390  * having to check for error everywhere).
2391  */
2392     char_u  *
2393 ml_get(lnum)
2394     linenr_T    lnum;
2395 {
2396     return ml_get_buf(curbuf, lnum, FALSE);
2397 }
2398
2399 /*
2400  * ml_get_pos: get pointer to position 'pos'
2401  */
2402     char_u *
2403 ml_get_pos(pos)
2404     pos_T       *pos;
2405 {
2406     return (ml_get_buf(curbuf, pos->lnum, FALSE) + pos->col);
2407 }
2408
2409 /*
2410  * ml_get_curline: get pointer to cursor line.
2411  */
2412     char_u *
2413 ml_get_curline()
2414 {
2415     return ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE);
2416 }
2417
2418 /*
2419  * ml_get_cursor: get pointer to cursor position
2420  */
2421     char_u *
2422 ml_get_cursor()
2423 {
2424     return (ml_get_buf(curbuf, curwin->w_cursor.lnum, FALSE) +
2425                                                         curwin->w_cursor.col);
2426 }
2427
2428 /*
2429  * get a pointer to a line in a specific buffer
2430  *
2431  * "will_change": if TRUE mark the buffer dirty (chars in the line will be
2432  * changed)
2433  */
2434     char_u  *
2435 ml_get_buf(buf, lnum, will_change)
2436     buf_T       *buf;
2437     linenr_T    lnum;
2438     int         will_change;            /* line will be changed */
2439 {
2440     bhdr_T      *hp;
2441     DATA_BL     *dp;
2442     char_u      *ptr;
2443     static int  recursive = 0;
2444
2445     if (lnum > buf->b_ml.ml_line_count) /* invalid line number */
2446     {
2447         if (recursive == 0)
2448         {
2449             /* Avoid giving this message for a recursive call, may happen when
2450              * the GUI redraws part of the text. */
2451             ++recursive;
2452             EMSGN(_("E315: ml_get: invalid lnum: %ld"), lnum);
2453             --recursive;
2454         }
2455 errorret:
2456         STRCPY(IObuff, "???");
2457         return IObuff;
2458     }
2459     if (lnum <= 0)                      /* pretend line 0 is line 1 */
2460         lnum = 1;
2461
2462     if (buf->b_ml.ml_mfp == NULL)       /* there are no lines */
2463         return (char_u *)"";
2464
2465     /*
2466      * See if it is the same line as requested last time.
2467      * Otherwise may need to flush last used line.
2468      * Don't use the last used line when 'swapfile' is reset, need to load all
2469      * blocks.
2470      */
2471     if (buf->b_ml.ml_line_lnum != lnum || mf_dont_release)
2472     {
2473         ml_flush_line(buf);
2474
2475         /*
2476          * Find the data block containing the line.
2477          * This also fills the stack with the blocks from the root to the data
2478          * block and releases any locked block.
2479          */
2480         if ((hp = ml_find_line(buf, lnum, ML_FIND)) == NULL)
2481         {
2482             if (recursive == 0)
2483             {
2484                 /* Avoid giving this message for a recursive call, may happen
2485                  * when the GUI redraws part of the text. */
2486                 ++recursive;
2487                 EMSGN(_("E316: ml_get: cannot find line %ld"), lnum);
2488                 --recursive;
2489             }
2490             goto errorret;
2491         }
2492
2493         dp = (DATA_BL *)(hp->bh_data);
2494
2495         ptr = (char_u *)dp + ((dp->db_index[lnum - buf->b_ml.ml_locked_low]) & DB_INDEX_MASK);
2496         buf->b_ml.ml_line_ptr = ptr;
2497         buf->b_ml.ml_line_lnum = lnum;
2498         buf->b_ml.ml_flags &= ~ML_LINE_DIRTY;
2499     }
2500     if (will_change)
2501         buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
2502
2503     return buf->b_ml.ml_line_ptr;
2504 }
2505
2506 /*
2507  * Check if a line that was just obtained by a call to ml_get
2508  * is in allocated memory.
2509  */
2510     int
2511 ml_line_alloced()
2512 {
2513     return (curbuf->b_ml.ml_flags & ML_LINE_DIRTY);
2514 }
2515
2516 /*
2517  * Append a line after lnum (may be 0 to insert a line in front of the file).
2518  * "line" does not need to be allocated, but can't be another line in a
2519  * buffer, unlocking may make it invalid.
2520  *
2521  *   newfile: TRUE when starting to edit a new file, meaning that pe_old_lnum
2522  *              will be set for recovery
2523  * Check: The caller of this function should probably also call
2524  * appended_lines().
2525  *
2526  * return FAIL for failure, OK otherwise
2527  */
2528     int
2529 ml_append(lnum, line, len, newfile)
2530     linenr_T    lnum;           /* append after this line (can be 0) */
2531     char_u      *line;          /* text of the new line */
2532     colnr_T     len;            /* length of new line, including NUL, or 0 */
2533     int         newfile;        /* flag, see above */
2534 {
2535     /* When starting up, we might still need to create the memfile */
2536     if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
2537         return FAIL;
2538
2539     if (curbuf->b_ml.ml_line_lnum != 0)
2540         ml_flush_line(curbuf);
2541     return ml_append_int(curbuf, lnum, line, len, newfile, FALSE);
2542 }
2543
2544 #if defined(FEAT_SPELL) || defined(PROTO)
2545 /*
2546  * Like ml_append() but for an arbitrary buffer.  The buffer must already have
2547  * a memline.
2548  */
2549     int
2550 ml_append_buf(buf, lnum, line, len, newfile)
2551     buf_T       *buf;
2552     linenr_T    lnum;           /* append after this line (can be 0) */
2553     char_u      *line;          /* text of the new line */
2554     colnr_T     len;            /* length of new line, including NUL, or 0 */
2555     int         newfile;        /* flag, see above */
2556 {
2557     if (buf->b_ml.ml_mfp == NULL)
2558         return FAIL;
2559
2560     if (buf->b_ml.ml_line_lnum != 0)
2561         ml_flush_line(buf);
2562     return ml_append_int(buf, lnum, line, len, newfile, FALSE);
2563 }
2564 #endif
2565
2566     static int
2567 ml_append_int(buf, lnum, line, len, newfile, mark)
2568     buf_T       *buf;
2569     linenr_T    lnum;           /* append after this line (can be 0) */
2570     char_u      *line;          /* text of the new line */
2571     colnr_T     len;            /* length of line, including NUL, or 0 */
2572     int         newfile;        /* flag, see above */
2573     int         mark;           /* mark the new line */
2574 {
2575     int         i;
2576     int         line_count;     /* number of indexes in current block */
2577     int         offset;
2578     int         from, to;
2579     int         space_needed;   /* space needed for new line */
2580     int         page_size;
2581     int         page_count;
2582     int         db_idx;         /* index for lnum in data block */
2583     bhdr_T      *hp;
2584     memfile_T   *mfp;
2585     DATA_BL     *dp;
2586     PTR_BL      *pp;
2587     infoptr_T   *ip;
2588
2589                                         /* lnum out of range */
2590     if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL)
2591         return FAIL;
2592
2593     if (lowest_marked && lowest_marked > lnum)
2594         lowest_marked = lnum + 1;
2595
2596     if (len == 0)
2597         len = (colnr_T)STRLEN(line) + 1;        /* space needed for the text */
2598     space_needed = len + INDEX_SIZE;    /* space needed for text + index */
2599
2600     mfp = buf->b_ml.ml_mfp;
2601     page_size = mfp->mf_page_size;
2602
2603 /*
2604  * find the data block containing the previous line
2605  * This also fills the stack with the blocks from the root to the data block
2606  * This also releases any locked block.
2607  */
2608     if ((hp = ml_find_line(buf, lnum == 0 ? (linenr_T)1 : lnum,
2609                                                           ML_INSERT)) == NULL)
2610         return FAIL;
2611
2612     buf->b_ml.ml_flags &= ~ML_EMPTY;
2613
2614     if (lnum == 0)              /* got line one instead, correct db_idx */
2615         db_idx = -1;            /* careful, it is negative! */
2616     else
2617         db_idx = lnum - buf->b_ml.ml_locked_low;
2618                 /* get line count before the insertion */
2619     line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
2620
2621     dp = (DATA_BL *)(hp->bh_data);
2622
2623 /*
2624  * If
2625  * - there is not enough room in the current block
2626  * - appending to the last line in the block
2627  * - not appending to the last line in the file
2628  * insert in front of the next block.
2629  */
2630     if ((int)dp->db_free < space_needed && db_idx == line_count - 1
2631                                             && lnum < buf->b_ml.ml_line_count)
2632     {
2633         /*
2634          * Now that the line is not going to be inserted in the block that we
2635          * expected, the line count has to be adjusted in the pointer blocks
2636          * by using ml_locked_lineadd.
2637          */
2638         --(buf->b_ml.ml_locked_lineadd);
2639         --(buf->b_ml.ml_locked_high);
2640         if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL)
2641             return FAIL;
2642
2643         db_idx = -1;                /* careful, it is negative! */
2644                     /* get line count before the insertion */
2645         line_count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low;
2646         CHECK(buf->b_ml.ml_locked_low != lnum + 1, "locked_low != lnum + 1");
2647
2648         dp = (DATA_BL *)(hp->bh_data);
2649     }
2650
2651     ++buf->b_ml.ml_line_count;
2652
2653     if ((int)dp->db_free >= space_needed)       /* enough room in data block */
2654     {
2655 /*
2656  * Insert new line in existing data block, or in data block allocated above.
2657  */
2658         dp->db_txt_start -= len;
2659         dp->db_free -= space_needed;
2660         ++(dp->db_line_count);
2661
2662         /*
2663          * move the text of the lines that follow to the front
2664          * adjust the indexes of the lines that follow
2665          */
2666         if (line_count > db_idx + 1)        /* if there are following lines */
2667         {
2668             /*
2669              * Offset is the start of the previous line.
2670              * This will become the character just after the new line.
2671              */
2672             if (db_idx < 0)
2673                 offset = dp->db_txt_end;
2674             else
2675                 offset = ((dp->db_index[db_idx]) & DB_INDEX_MASK);
2676             mch_memmove((char *)dp + dp->db_txt_start,
2677                                           (char *)dp + dp->db_txt_start + len,
2678                                  (size_t)(offset - (dp->db_txt_start + len)));
2679             for (i = line_count - 1; i > db_idx; --i)
2680                 dp->db_index[i + 1] = dp->db_index[i] - len;
2681             dp->db_index[db_idx + 1] = offset - len;
2682         }
2683         else                                /* add line at the end */
2684             dp->db_index[db_idx + 1] = dp->db_txt_start;
2685
2686         /*
2687          * copy the text into the block
2688          */
2689         mch_memmove((char *)dp + dp->db_index[db_idx + 1], line, (size_t)len);
2690         if (mark)
2691             dp->db_index[db_idx + 1] |= DB_MARKED;
2692
2693         /*
2694          * Mark the block dirty.
2695          */
2696         buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
2697         if (!newfile)
2698             buf->b_ml.ml_flags |= ML_LOCKED_POS;
2699     }
2700     else            /* not enough space in data block */
2701     {
2702 /*
2703  * If there is not enough room we have to create a new data block and copy some
2704  * lines into it.
2705  * Then we have to insert an entry in the pointer block.
2706  * If this pointer block also is full, we go up another block, and so on, up
2707  * to the root if necessary.
2708  * The line counts in the pointer blocks have already been adjusted by
2709  * ml_find_line().
2710  */
2711         long        line_count_left, line_count_right;
2712         int         page_count_left, page_count_right;
2713         bhdr_T      *hp_left;
2714         bhdr_T      *hp_right;
2715         bhdr_T      *hp_new;
2716         int         lines_moved;
2717         int         data_moved = 0;         /* init to shut up gcc */
2718         int         total_moved = 0;        /* init to shut up gcc */
2719         DATA_BL     *dp_right, *dp_left;
2720         int         stack_idx;
2721         int         in_left;
2722         int         lineadd;
2723         blocknr_T   bnum_left, bnum_right;
2724         linenr_T    lnum_left, lnum_right;
2725         int         pb_idx;
2726         PTR_BL      *pp_new;
2727
2728         /*
2729          * We are going to allocate a new data block. Depending on the
2730          * situation it will be put to the left or right of the existing
2731          * block.  If possible we put the new line in the left block and move
2732          * the lines after it to the right block. Otherwise the new line is
2733          * also put in the right block. This method is more efficient when
2734          * inserting a lot of lines at one place.
2735          */
2736         if (db_idx < 0)         /* left block is new, right block is existing */
2737         {
2738             lines_moved = 0;
2739             in_left = TRUE;
2740             /* space_needed does not change */
2741         }
2742         else                    /* left block is existing, right block is new */
2743         {
2744             lines_moved = line_count - db_idx - 1;
2745             if (lines_moved == 0)
2746                 in_left = FALSE;        /* put new line in right block */
2747                                         /* space_needed does not change */
2748             else
2749             {
2750                 data_moved = ((dp->db_index[db_idx]) & DB_INDEX_MASK) -
2751                                                             dp->db_txt_start;
2752                 total_moved = data_moved + lines_moved * INDEX_SIZE;
2753                 if ((int)dp->db_free + total_moved >= space_needed)
2754                 {
2755                     in_left = TRUE;     /* put new line in left block */
2756                     space_needed = total_moved;
2757                 }
2758                 else
2759                 {
2760                     in_left = FALSE;        /* put new line in right block */
2761                     space_needed += total_moved;
2762                 }
2763             }
2764         }
2765
2766         page_count = ((space_needed + HEADER_SIZE) + page_size - 1) / page_size;
2767         if ((hp_new = ml_new_data(mfp, newfile, page_count)) == NULL)
2768         {
2769                         /* correct line counts in pointer blocks */
2770             --(buf->b_ml.ml_locked_lineadd);
2771             --(buf->b_ml.ml_locked_high);
2772             return FAIL;
2773         }
2774         if (db_idx < 0)         /* left block is new */
2775         {
2776             hp_left = hp_new;
2777             hp_right = hp;
2778             line_count_left = 0;
2779             line_count_right = line_count;
2780         }
2781         else                    /* right block is new */
2782         {
2783             hp_left = hp;
2784             hp_right = hp_new;
2785             line_count_left = line_count;
2786             line_count_right = 0;
2787         }
2788         dp_right = (DATA_BL *)(hp_right->bh_data);
2789         dp_left = (DATA_BL *)(hp_left->bh_data);
2790         bnum_left = hp_left->bh_bnum;
2791         bnum_right = hp_right->bh_bnum;
2792         page_count_left = hp_left->bh_page_count;
2793         page_count_right = hp_right->bh_page_count;
2794
2795         /*
2796          * May move the new line into the right/new block.
2797          */
2798         if (!in_left)
2799         {
2800             dp_right->db_txt_start -= len;
2801             dp_right->db_free -= len + INDEX_SIZE;
2802             dp_right->db_index[0] = dp_right->db_txt_start;
2803             if (mark)
2804                 dp_right->db_index[0] |= DB_MARKED;
2805
2806             mch_memmove((char *)dp_right + dp_right->db_txt_start,
2807                                                            line, (size_t)len);
2808             ++line_count_right;
2809         }
2810         /*
2811          * may move lines from the left/old block to the right/new one.
2812          */
2813         if (lines_moved)
2814         {
2815             /*
2816              */
2817             dp_right->db_txt_start -= data_moved;
2818             dp_right->db_free -= total_moved;
2819             mch_memmove((char *)dp_right + dp_right->db_txt_start,
2820                         (char *)dp_left + dp_left->db_txt_start,
2821                         (size_t)data_moved);
2822             offset = dp_right->db_txt_start - dp_left->db_txt_start;
2823             dp_left->db_txt_start += data_moved;
2824             dp_left->db_free += total_moved;
2825
2826             /*
2827              * update indexes in the new block
2828              */
2829             for (to = line_count_right, from = db_idx + 1;
2830                                          from < line_count_left; ++from, ++to)
2831                 dp_right->db_index[to] = dp->db_index[from] + offset;
2832             line_count_right += lines_moved;
2833             line_count_left -= lines_moved;
2834         }
2835
2836         /*
2837          * May move the new line into the left (old or new) block.
2838          */
2839         if (in_left)
2840         {
2841             dp_left->db_txt_start -= len;
2842             dp_left->db_free -= len + INDEX_SIZE;
2843             dp_left->db_index[line_count_left] = dp_left->db_txt_start;
2844             if (mark)
2845                 dp_left->db_index[line_count_left] |= DB_MARKED;
2846             mch_memmove((char *)dp_left + dp_left->db_txt_start,
2847                                                            line, (size_t)len);
2848             ++line_count_left;
2849         }
2850
2851         if (db_idx < 0)         /* left block is new */
2852         {
2853             lnum_left = lnum + 1;
2854             lnum_right = 0;
2855         }
2856         else                    /* right block is new */
2857         {
2858             lnum_left = 0;
2859             if (in_left)
2860                 lnum_right = lnum + 2;
2861             else
2862                 lnum_right = lnum + 1;
2863         }
2864         dp_left->db_line_count = line_count_left;
2865         dp_right->db_line_count = line_count_right;
2866
2867         /*
2868          * release the two data blocks
2869          * The new one (hp_new) already has a correct blocknumber.
2870          * The old one (hp, in ml_locked) gets a positive blocknumber if
2871          * we changed it and we are not editing a new file.
2872          */
2873         if (lines_moved || in_left)
2874             buf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
2875         if (!newfile && db_idx >= 0 && in_left)
2876             buf->b_ml.ml_flags |= ML_LOCKED_POS;
2877         mf_put(mfp, hp_new, TRUE, FALSE);
2878
2879         /*
2880          * flush the old data block
2881          * set ml_locked_lineadd to 0, because the updating of the
2882          * pointer blocks is done below
2883          */
2884         lineadd = buf->b_ml.ml_locked_lineadd;
2885         buf->b_ml.ml_locked_lineadd = 0;
2886         ml_find_line(buf, (linenr_T)0, ML_FLUSH);   /* flush data block */
2887
2888         /*
2889          * update pointer blocks for the new data block
2890          */
2891         for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0;
2892                                                                   --stack_idx)
2893         {
2894             ip = &(buf->b_ml.ml_stack[stack_idx]);
2895             pb_idx = ip->ip_index;
2896             if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
2897                 return FAIL;
2898             pp = (PTR_BL *)(hp->bh_data);   /* must be pointer block */
2899             if (pp->pb_id != PTR_ID)
2900             {
2901                 EMSG(_("E317: pointer block id wrong 3"));
2902                 mf_put(mfp, hp, FALSE, FALSE);
2903                 return FAIL;
2904             }
2905             /*
2906              * TODO: If the pointer block is full and we are adding at the end
2907              * try to insert in front of the next block
2908              */
2909             /* block not full, add one entry */
2910             if (pp->pb_count < pp->pb_count_max)
2911             {
2912                 if (pb_idx + 1 < (int)pp->pb_count)
2913                     mch_memmove(&pp->pb_pointer[pb_idx + 2],
2914                                 &pp->pb_pointer[pb_idx + 1],
2915                         (size_t)(pp->pb_count - pb_idx - 1) * sizeof(PTR_EN));
2916                 ++pp->pb_count;
2917                 pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
2918                 pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
2919                 pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
2920                 pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
2921                 pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
2922                 pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
2923
2924                 if (lnum_left != 0)
2925                     pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
2926                 if (lnum_right != 0)
2927                     pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
2928
2929                 mf_put(mfp, hp, TRUE, FALSE);
2930                 buf->b_ml.ml_stack_top = stack_idx + 1;     /* truncate stack */
2931
2932                 if (lineadd)
2933                 {
2934                     --(buf->b_ml.ml_stack_top);
2935                     /* fix line count for rest of blocks in the stack */
2936                     ml_lineadd(buf, lineadd);
2937                                                         /* fix stack itself */
2938                     buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
2939                                                                       lineadd;
2940                     ++(buf->b_ml.ml_stack_top);
2941                 }
2942
2943                 /*
2944                  * We are finished, break the loop here.
2945                  */
2946                 break;
2947             }
2948             else                        /* pointer block full */
2949             {
2950                 /*
2951                  * split the pointer block
2952                  * allocate a new pointer block
2953                  * move some of the pointer into the new block
2954                  * prepare for updating the parent block
2955                  */
2956                 for (;;)        /* do this twice when splitting block 1 */
2957                 {
2958                     hp_new = ml_new_ptr(mfp);
2959                     if (hp_new == NULL)     /* TODO: try to fix tree */
2960                         return FAIL;
2961                     pp_new = (PTR_BL *)(hp_new->bh_data);
2962
2963                     if (hp->bh_bnum != 1)
2964                         break;
2965
2966                     /*
2967                      * if block 1 becomes full the tree is given an extra level
2968                      * The pointers from block 1 are moved into the new block.
2969                      * block 1 is updated to point to the new block
2970                      * then continue to split the new block
2971                      */
2972                     mch_memmove(pp_new, pp, (size_t)page_size);
2973                     pp->pb_count = 1;
2974                     pp->pb_pointer[0].pe_bnum = hp_new->bh_bnum;
2975                     pp->pb_pointer[0].pe_line_count = buf->b_ml.ml_line_count;
2976                     pp->pb_pointer[0].pe_old_lnum = 1;
2977                     pp->pb_pointer[0].pe_page_count = 1;
2978                     mf_put(mfp, hp, TRUE, FALSE);   /* release block 1 */
2979                     hp = hp_new;                /* new block is to be split */
2980                     pp = pp_new;
2981                     CHECK(stack_idx != 0, _("stack_idx should be 0"));
2982                     ip->ip_index = 0;
2983                     ++stack_idx;        /* do block 1 again later */
2984                 }
2985                 /*
2986                  * move the pointers after the current one to the new block
2987                  * If there are none, the new entry will be in the new block.
2988                  */
2989                 total_moved = pp->pb_count - pb_idx - 1;
2990                 if (total_moved)
2991                 {
2992                     mch_memmove(&pp_new->pb_pointer[0],
2993                                 &pp->pb_pointer[pb_idx + 1],
2994                                 (size_t)(total_moved) * sizeof(PTR_EN));
2995                     pp_new->pb_count = total_moved;
2996                     pp->pb_count -= total_moved - 1;
2997                     pp->pb_pointer[pb_idx + 1].pe_bnum = bnum_right;
2998                     pp->pb_pointer[pb_idx + 1].pe_line_count = line_count_right;
2999                     pp->pb_pointer[pb_idx + 1].pe_page_count = page_count_right;
3000                     if (lnum_right)
3001                         pp->pb_pointer[pb_idx + 1].pe_old_lnum = lnum_right;
3002                 }
3003                 else
3004                 {
3005                     pp_new->pb_count = 1;
3006                     pp_new->pb_pointer[0].pe_bnum = bnum_right;
3007                     pp_new->pb_pointer[0].pe_line_count = line_count_right;
3008                     pp_new->pb_pointer[0].pe_page_count = page_count_right;
3009                     pp_new->pb_pointer[0].pe_old_lnum = lnum_right;
3010                 }
3011                 pp->pb_pointer[pb_idx].pe_bnum = bnum_left;
3012                 pp->pb_pointer[pb_idx].pe_line_count = line_count_left;
3013                 pp->pb_pointer[pb_idx].pe_page_count = page_count_left;
3014                 if (lnum_left)
3015                     pp->pb_pointer[pb_idx].pe_old_lnum = lnum_left;
3016                 lnum_left = 0;
3017                 lnum_right = 0;
3018
3019                 /*
3020                  * recompute line counts
3021                  */
3022                 line_count_right = 0;
3023                 for (i = 0; i < (int)pp_new->pb_count; ++i)
3024                     line_count_right += pp_new->pb_pointer[i].pe_line_count;
3025                 line_count_left = 0;
3026                 for (i = 0; i < (int)pp->pb_count; ++i)
3027                     line_count_left += pp->pb_pointer[i].pe_line_count;
3028
3029                 bnum_left = hp->bh_bnum;
3030                 bnum_right = hp_new->bh_bnum;
3031                 page_count_left = 1;
3032                 page_count_right = 1;
3033                 mf_put(mfp, hp, TRUE, FALSE);
3034                 mf_put(mfp, hp_new, TRUE, FALSE);
3035             }
3036         }
3037
3038         /*
3039          * Safety check: fallen out of for loop?
3040          */
3041         if (stack_idx < 0)
3042         {
3043             EMSG(_("E318: Updated too many blocks?"));
3044             buf->b_ml.ml_stack_top = 0; /* invalidate stack */
3045         }
3046     }
3047
3048 #ifdef FEAT_BYTEOFF
3049     /* The line was inserted below 'lnum' */
3050     ml_updatechunk(buf, lnum + 1, (long)len, ML_CHNK_ADDLINE);
3051 #endif
3052 #ifdef FEAT_NETBEANS_INTG
3053     if (netbeans_active())
3054     {
3055         if (STRLEN(line) > 0)
3056             netbeans_inserted(buf, lnum+1, (colnr_T)0, line, (int)STRLEN(line));
3057         netbeans_inserted(buf, lnum+1, (colnr_T)STRLEN(line),
3058                                                            (char_u *)"\n", 1);
3059     }
3060 #endif
3061     return OK;
3062 }
3063
3064 /*
3065  * Replace line lnum, with buffering, in current buffer.
3066  *
3067  * If "copy" is TRUE, make a copy of the line, otherwise the line has been
3068  * copied to allocated memory already.
3069  *
3070  * Check: The caller of this function should probably also call
3071  * changed_lines(), unless update_screen(NOT_VALID) is used.
3072  *
3073  * return FAIL for failure, OK otherwise
3074  */
3075     int
3076 ml_replace(lnum, line, copy)
3077     linenr_T    lnum;
3078     char_u      *line;
3079     int         copy;
3080 {
3081     if (line == NULL)           /* just checking... */
3082         return FAIL;
3083
3084     /* When starting up, we might still need to create the memfile */
3085     if (curbuf->b_ml.ml_mfp == NULL && open_buffer(FALSE, NULL, 0) == FAIL)
3086         return FAIL;
3087
3088     if (copy && (line = vim_strsave(line)) == NULL) /* allocate memory */
3089         return FAIL;
3090 #ifdef FEAT_NETBEANS_INTG
3091     if (netbeans_active())
3092     {
3093         netbeans_removed(curbuf, lnum, 0, (long)STRLEN(ml_get(lnum)));
3094         netbeans_inserted(curbuf, lnum, 0, line, (int)STRLEN(line));
3095     }
3096 #endif
3097     if (curbuf->b_ml.ml_line_lnum != lnum)          /* other line buffered */
3098         ml_flush_line(curbuf);                      /* flush it */
3099     else if (curbuf->b_ml.ml_flags & ML_LINE_DIRTY) /* same line allocated */
3100         vim_free(curbuf->b_ml.ml_line_ptr);         /* free it */
3101     curbuf->b_ml.ml_line_ptr = line;
3102     curbuf->b_ml.ml_line_lnum = lnum;
3103     curbuf->b_ml.ml_flags = (curbuf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY;
3104
3105     return OK;
3106 }
3107
3108 /*
3109  * Delete line 'lnum' in the current buffer.
3110  *
3111  * Check: The caller of this function should probably also call
3112  * deleted_lines() after this.
3113  *
3114  * return FAIL for failure, OK otherwise
3115  */
3116     int
3117 ml_delete(lnum, message)
3118     linenr_T    lnum;
3119     int         message;
3120 {
3121     ml_flush_line(curbuf);
3122     return ml_delete_int(curbuf, lnum, message);
3123 }
3124
3125     static int
3126 ml_delete_int(buf, lnum, message)
3127     buf_T       *buf;
3128     linenr_T    lnum;
3129     int         message;
3130 {
3131     bhdr_T      *hp;
3132     memfile_T   *mfp;
3133     DATA_BL     *dp;
3134     PTR_BL      *pp;
3135     infoptr_T   *ip;
3136     int         count;      /* number of entries in block */
3137     int         idx;
3138     int         stack_idx;
3139     int         text_start;
3140     int         line_start;
3141     long        line_size;
3142     int         i;
3143
3144     if (lnum < 1 || lnum > buf->b_ml.ml_line_count)
3145         return FAIL;
3146
3147     if (lowest_marked && lowest_marked > lnum)
3148         lowest_marked--;
3149
3150 /*
3151  * If the file becomes empty the last line is replaced by an empty line.
3152  */
3153     if (buf->b_ml.ml_line_count == 1)       /* file becomes empty */
3154     {
3155         if (message
3156 #ifdef FEAT_NETBEANS_INTG
3157                 && !netbeansSuppressNoLines
3158 #endif
3159            )
3160             set_keep_msg((char_u *)_(no_lines_msg), 0);
3161
3162         /* FEAT_BYTEOFF already handled in there, dont worry 'bout it below */
3163         i = ml_replace((linenr_T)1, (char_u *)"", TRUE);
3164         buf->b_ml.ml_flags |= ML_EMPTY;
3165
3166         return i;
3167     }
3168
3169 /*
3170  * find the data block containing the line
3171  * This also fills the stack with the blocks from the root to the data block
3172  * This also releases any locked block.
3173  */
3174     mfp = buf->b_ml.ml_mfp;
3175     if (mfp == NULL)
3176         return FAIL;
3177
3178     if ((hp = ml_find_line(buf, lnum, ML_DELETE)) == NULL)
3179         return FAIL;
3180
3181     dp = (DATA_BL *)(hp->bh_data);
3182     /* compute line count before the delete */
3183     count = (long)(buf->b_ml.ml_locked_high)
3184                                         - (long)(buf->b_ml.ml_locked_low) + 2;
3185     idx = lnum - buf->b_ml.ml_locked_low;
3186
3187     --buf->b_ml.ml_line_count;
3188
3189     line_start = ((dp->db_index[idx]) & DB_INDEX_MASK);
3190     if (idx == 0)               /* first line in block, text at the end */
3191         line_size = dp->db_txt_end - line_start;
3192     else
3193         line_size = ((dp->db_index[idx - 1]) & DB_INDEX_MASK) - line_start;
3194
3195 #ifdef FEAT_NETBEANS_INTG
3196     if (netbeans_active())
3197         netbeans_removed(buf, lnum, 0, (long)line_size);
3198 #endif
3199
3200 /*
3201  * special case: If there is only one line in the data block it becomes empty.
3202  * Then we have to remove the entry, pointing to this data block, from the
3203  * pointer block. If this pointer block also becomes empty, we go up another
3204  * block, and so on, up to the root if necessary.
3205  * The line counts in the pointer blocks have already been adjusted by
3206  * ml_find_line().
3207  */
3208     if (count == 1)
3209     {
3210         mf_free(mfp, hp);       /* free the data block */
3211         buf->b_ml.ml_locked = NULL;
3212
3213         for (stack_idx = buf->b_ml.ml_stack_top - 1; stack_idx >= 0; --stack_idx)
3214         {
3215             buf->b_ml.ml_stack_top = 0;     /* stack is invalid when failing */
3216             ip = &(buf->b_ml.ml_stack[stack_idx]);
3217             idx = ip->ip_index;
3218             if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
3219                 return FAIL;
3220             pp = (PTR_BL *)(hp->bh_data);   /* must be pointer block */
3221             if (pp->pb_id != PTR_ID)
3222             {
3223                 EMSG(_("E317: pointer block id wrong 4"));
3224                 mf_put(mfp, hp, FALSE, FALSE);
3225                 return FAIL;
3226             }
3227             count = --(pp->pb_count);
3228             if (count == 0)         /* the pointer block becomes empty! */
3229                 mf_free(mfp, hp);
3230             else
3231             {
3232                 if (count != idx)       /* move entries after the deleted one */
3233                     mch_memmove(&pp->pb_pointer[idx], &pp->pb_pointer[idx + 1],
3234                                       (size_t)(count - idx) * sizeof(PTR_EN));
3235                 mf_put(mfp, hp, TRUE, FALSE);
3236
3237                 buf->b_ml.ml_stack_top = stack_idx;     /* truncate stack */
3238                 /* fix line count for rest of blocks in the stack */
3239                 if (buf->b_ml.ml_locked_lineadd != 0)
3240                 {
3241                     ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
3242                     buf->b_ml.ml_stack[buf->b_ml.ml_stack_top].ip_high +=
3243                                                   buf->b_ml.ml_locked_lineadd;
3244                 }
3245                 ++(buf->b_ml.ml_stack_top);
3246
3247                 break;
3248             }
3249         }
3250         CHECK(stack_idx < 0, _("deleted block 1?"));
3251     }
3252     else
3253     {
3254         /*
3255          * delete the text by moving the next lines forwards
3256          */
3257         text_start = dp->db_txt_start;
3258         mch_memmove((char *)dp + text_start + line_size,
3259                   (char *)dp + text_start, (size_t)(line_start - text_start));
3260
3261         /*
3262          * delete the index by moving the next indexes backwards
3263          * Adjust the indexes for the text movement.
3264          */
3265         for (i = idx; i < count - 1; ++i)
3266             dp->db_index[i] = dp->db_index[i + 1] + line_size;
3267
3268         dp->db_free += line_size + INDEX_SIZE;
3269         dp->db_txt_start += line_size;
3270         --(dp->db_line_count);
3271
3272         /*
3273          * mark the block dirty and make sure it is in the file (for recovery)
3274          */
3275         buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
3276     }
3277
3278 #ifdef FEAT_BYTEOFF
3279     ml_updatechunk(buf, lnum, line_size, ML_CHNK_DELLINE);
3280 #endif
3281     return OK;
3282 }
3283
3284 /*
3285  * set the B_MARKED flag for line 'lnum'
3286  */
3287     void
3288 ml_setmarked(lnum)
3289     linenr_T lnum;
3290 {
3291     bhdr_T    *hp;
3292     DATA_BL *dp;
3293                                     /* invalid line number */
3294     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count
3295                                                || curbuf->b_ml.ml_mfp == NULL)
3296         return;                     /* give error message? */
3297
3298     if (lowest_marked == 0 || lowest_marked > lnum)
3299         lowest_marked = lnum;
3300
3301     /*
3302      * find the data block containing the line
3303      * This also fills the stack with the blocks from the root to the data block
3304      * This also releases any locked block.
3305      */
3306     if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
3307         return;             /* give error message? */
3308
3309     dp = (DATA_BL *)(hp->bh_data);
3310     dp->db_index[lnum - curbuf->b_ml.ml_locked_low] |= DB_MARKED;
3311     curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
3312 }
3313
3314 /*
3315  * find the first line with its B_MARKED flag set
3316  */
3317     linenr_T
3318 ml_firstmarked()
3319 {
3320     bhdr_T      *hp;
3321     DATA_BL     *dp;
3322     linenr_T    lnum;
3323     int         i;
3324
3325     if (curbuf->b_ml.ml_mfp == NULL)
3326         return (linenr_T) 0;
3327
3328     /*
3329      * The search starts with lowest_marked line. This is the last line where
3330      * a mark was found, adjusted by inserting/deleting lines.
3331      */
3332     for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; )
3333     {
3334         /*
3335          * Find the data block containing the line.
3336          * This also fills the stack with the blocks from the root to the data
3337          * block This also releases any locked block.
3338          */
3339         if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
3340             return (linenr_T)0;             /* give error message? */
3341
3342         dp = (DATA_BL *)(hp->bh_data);
3343
3344         for (i = lnum - curbuf->b_ml.ml_locked_low;
3345                             lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
3346             if ((dp->db_index[i]) & DB_MARKED)
3347             {
3348                 (dp->db_index[i]) &= DB_INDEX_MASK;
3349                 curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
3350                 lowest_marked = lnum + 1;
3351                 return lnum;
3352             }
3353     }
3354
3355     return (linenr_T) 0;
3356 }
3357
3358 /*
3359  * clear all DB_MARKED flags
3360  */
3361     void
3362 ml_clearmarked()
3363 {
3364     bhdr_T      *hp;
3365     DATA_BL     *dp;
3366     linenr_T    lnum;
3367     int         i;
3368
3369     if (curbuf->b_ml.ml_mfp == NULL)        /* nothing to do */
3370         return;
3371
3372     /*
3373      * The search starts with line lowest_marked.
3374      */
3375     for (lnum = lowest_marked; lnum <= curbuf->b_ml.ml_line_count; )
3376     {
3377         /*
3378          * Find the data block containing the line.
3379          * This also fills the stack with the blocks from the root to the data
3380          * block and releases any locked block.
3381          */
3382         if ((hp = ml_find_line(curbuf, lnum, ML_FIND)) == NULL)
3383             return;             /* give error message? */
3384
3385         dp = (DATA_BL *)(hp->bh_data);
3386
3387         for (i = lnum - curbuf->b_ml.ml_locked_low;
3388                             lnum <= curbuf->b_ml.ml_locked_high; ++i, ++lnum)
3389             if ((dp->db_index[i]) & DB_MARKED)
3390             {
3391                 (dp->db_index[i]) &= DB_INDEX_MASK;
3392                 curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
3393             }
3394     }
3395
3396     lowest_marked = 0;
3397     return;
3398 }
3399
3400 /*
3401  * flush ml_line if necessary
3402  */
3403     static void
3404 ml_flush_line(buf)
3405     buf_T       *buf;
3406 {
3407     bhdr_T      *hp;
3408     DATA_BL     *dp;
3409     linenr_T    lnum;
3410     char_u      *new_line;
3411     char_u      *old_line;
3412     colnr_T     new_len;
3413     int         old_len;
3414     int         extra;
3415     int         idx;
3416     int         start;
3417     int         count;
3418     int         i;
3419     static int  entered = FALSE;
3420
3421     if (buf->b_ml.ml_line_lnum == 0 || buf->b_ml.ml_mfp == NULL)
3422         return;         /* nothing to do */
3423
3424     if (buf->b_ml.ml_flags & ML_LINE_DIRTY)
3425     {
3426         /* This code doesn't work recursively, but Netbeans may call back here
3427          * when obtaining the cursor position. */
3428         if (entered)
3429             return;
3430         entered = TRUE;
3431
3432         lnum = buf->b_ml.ml_line_lnum;
3433         new_line = buf->b_ml.ml_line_ptr;
3434
3435         hp = ml_find_line(buf, lnum, ML_FIND);
3436         if (hp == NULL)
3437             EMSGN(_("E320: Cannot find line %ld"), lnum);
3438         else
3439         {
3440             dp = (DATA_BL *)(hp->bh_data);
3441             idx = lnum - buf->b_ml.ml_locked_low;
3442             start = ((dp->db_index[idx]) & DB_INDEX_MASK);
3443             old_line = (char_u *)dp + start;
3444             if (idx == 0)       /* line is last in block */
3445                 old_len = dp->db_txt_end - start;
3446             else                /* text of previous line follows */
3447                 old_len = (dp->db_index[idx - 1] & DB_INDEX_MASK) - start;
3448             new_len = (colnr_T)STRLEN(new_line) + 1;
3449             extra = new_len - old_len;      /* negative if lines gets smaller */
3450
3451             /*
3452              * if new line fits in data block, replace directly
3453              */
3454             if ((int)dp->db_free >= extra)
3455             {
3456                 /* if the length changes and there are following lines */
3457                 count = buf->b_ml.ml_locked_high - buf->b_ml.ml_locked_low + 1;
3458                 if (extra != 0 && idx < count - 1)
3459                 {
3460                     /* move text of following lines */
3461                     mch_memmove((char *)dp + dp->db_txt_start - extra,
3462                                 (char *)dp + dp->db_txt_start,
3463                                 (size_t)(start - dp->db_txt_start));
3464
3465                     /* adjust pointers of this and following lines */
3466                     for (i = idx + 1; i < count; ++i)
3467                         dp->db_index[i] -= extra;
3468                 }
3469                 dp->db_index[idx] -= extra;
3470
3471                 /* adjust free space */
3472                 dp->db_free -= extra;
3473                 dp->db_txt_start -= extra;
3474
3475                 /* copy new line into the data block */
3476                 mch_memmove(old_line - extra, new_line, (size_t)new_len);
3477                 buf->b_ml.ml_flags |= (ML_LOCKED_DIRTY | ML_LOCKED_POS);
3478 #ifdef FEAT_BYTEOFF
3479                 /* The else case is already covered by the insert and delete */
3480                 ml_updatechunk(buf, lnum, (long)extra, ML_CHNK_UPDLINE);
3481 #endif
3482             }
3483             else
3484             {
3485                 /*
3486                  * Cannot do it in one data block: Delete and append.
3487                  * Append first, because ml_delete_int() cannot delete the
3488                  * last line in a buffer, which causes trouble for a buffer
3489                  * that has only one line.
3490                  * Don't forget to copy the mark!
3491                  */
3492                 /* How about handling errors??? */
3493                 (void)ml_append_int(buf, lnum, new_line, new_len, FALSE,
3494                                              (dp->db_index[idx] & DB_MARKED));
3495                 (void)ml_delete_int(buf, lnum, FALSE);
3496             }
3497         }
3498         vim_free(new_line);
3499
3500         entered = FALSE;
3501     }
3502
3503     buf->b_ml.ml_line_lnum = 0;
3504 }
3505
3506 /*
3507  * create a new, empty, data block
3508  */
3509     static bhdr_T *
3510 ml_new_data(mfp, negative, page_count)
3511     memfile_T   *mfp;
3512     int         negative;
3513     int         page_count;
3514 {
3515     bhdr_T      *hp;
3516     DATA_BL     *dp;
3517
3518     if ((hp = mf_new(mfp, negative, page_count)) == NULL)
3519         return NULL;
3520
3521     dp = (DATA_BL *)(hp->bh_data);
3522     dp->db_id = DATA_ID;
3523     dp->db_txt_start = dp->db_txt_end = page_count * mfp->mf_page_size;
3524     dp->db_free = dp->db_txt_start - HEADER_SIZE;
3525     dp->db_line_count = 0;
3526
3527     return hp;
3528 }
3529
3530 /*
3531  * create a new, empty, pointer block
3532  */
3533     static bhdr_T *
3534 ml_new_ptr(mfp)
3535     memfile_T   *mfp;
3536 {
3537     bhdr_T      *hp;
3538     PTR_BL      *pp;
3539
3540     if ((hp = mf_new(mfp, FALSE, 1)) == NULL)
3541         return NULL;
3542
3543     pp = (PTR_BL *)(hp->bh_data);
3544     pp->pb_id = PTR_ID;
3545     pp->pb_count = 0;
3546     pp->pb_count_max = (short_u)((mfp->mf_page_size - sizeof(PTR_BL))
3547                                                         / sizeof(PTR_EN) + 1);
3548
3549     return hp;
3550 }
3551
3552 /*
3553  * lookup line 'lnum' in a memline
3554  *
3555  *   action: if ML_DELETE or ML_INSERT the line count is updated while searching
3556  *           if ML_FLUSH only flush a locked block
3557  *           if ML_FIND just find the line
3558  *
3559  * If the block was found it is locked and put in ml_locked.
3560  * The stack is updated to lead to the locked block. The ip_high field in
3561  * the stack is updated to reflect the last line in the block AFTER the
3562  * insert or delete, also if the pointer block has not been updated yet. But
3563  * if ml_locked != NULL ml_locked_lineadd must be added to ip_high.
3564  *
3565  * return: NULL for failure, pointer to block header otherwise
3566  */
3567     static bhdr_T *
3568 ml_find_line(buf, lnum, action)
3569     buf_T       *buf;
3570     linenr_T    lnum;
3571     int         action;
3572 {
3573     DATA_BL     *dp;
3574     PTR_BL      *pp;
3575     infoptr_T   *ip;
3576     bhdr_T      *hp;
3577     memfile_T   *mfp;
3578     linenr_T    t;
3579     blocknr_T   bnum, bnum2;
3580     int         dirty;
3581     linenr_T    low, high;
3582     int         top;
3583     int         page_count;
3584     int         idx;
3585
3586     mfp = buf->b_ml.ml_mfp;
3587
3588     /*
3589      * If there is a locked block check if the wanted line is in it.
3590      * If not, flush and release the locked block.
3591      * Don't do this for ML_INSERT_SAME, because the stack need to be updated.
3592      * Don't do this for ML_FLUSH, because we want to flush the locked block.
3593      * Don't do this when 'swapfile' is reset, we want to load all the blocks.
3594      */
3595     if (buf->b_ml.ml_locked)
3596     {
3597         if (ML_SIMPLE(action)
3598                 && buf->b_ml.ml_locked_low <= lnum
3599                 && buf->b_ml.ml_locked_high >= lnum
3600                 && !mf_dont_release)
3601         {
3602             /* remember to update pointer blocks and stack later */
3603             if (action == ML_INSERT)
3604             {
3605                 ++(buf->b_ml.ml_locked_lineadd);
3606                 ++(buf->b_ml.ml_locked_high);
3607             }
3608             else if (action == ML_DELETE)
3609             {
3610                 --(buf->b_ml.ml_locked_lineadd);
3611                 --(buf->b_ml.ml_locked_high);
3612             }
3613             return (buf->b_ml.ml_locked);
3614         }
3615
3616         mf_put(mfp, buf->b_ml.ml_locked, buf->b_ml.ml_flags & ML_LOCKED_DIRTY,
3617                                             buf->b_ml.ml_flags & ML_LOCKED_POS);
3618         buf->b_ml.ml_locked = NULL;
3619
3620         /*
3621          * If lines have been added or deleted in the locked block, need to
3622          * update the line count in pointer blocks.
3623          */
3624         if (buf->b_ml.ml_locked_lineadd != 0)
3625             ml_lineadd(buf, buf->b_ml.ml_locked_lineadd);
3626     }
3627
3628     if (action == ML_FLUSH)         /* nothing else to do */
3629         return NULL;
3630
3631     bnum = 1;                       /* start at the root of the tree */
3632     page_count = 1;
3633     low = 1;
3634     high = buf->b_ml.ml_line_count;
3635
3636     if (action == ML_FIND)      /* first try stack entries */
3637     {
3638         for (top = buf->b_ml.ml_stack_top - 1; top >= 0; --top)
3639         {
3640             ip = &(buf->b_ml.ml_stack[top]);
3641             if (ip->ip_low <= lnum && ip->ip_high >= lnum)
3642             {
3643                 bnum = ip->ip_bnum;
3644                 low = ip->ip_low;
3645                 high = ip->ip_high;
3646                 buf->b_ml.ml_stack_top = top;   /* truncate stack at prev entry */
3647                 break;
3648             }
3649         }
3650         if (top < 0)
3651             buf->b_ml.ml_stack_top = 0;         /* not found, start at the root */
3652     }
3653     else        /* ML_DELETE or ML_INSERT */
3654         buf->b_ml.ml_stack_top = 0;     /* start at the root */
3655
3656 /*
3657  * search downwards in the tree until a data block is found
3658  */
3659     for (;;)
3660     {
3661         if ((hp = mf_get(mfp, bnum, page_count)) == NULL)
3662             goto error_noblock;
3663
3664         /*
3665          * update high for insert/delete
3666          */
3667         if (action == ML_INSERT)
3668             ++high;
3669         else if (action == ML_DELETE)
3670             --high;
3671
3672         dp = (DATA_BL *)(hp->bh_data);
3673         if (dp->db_id == DATA_ID)       /* data block */
3674         {
3675             buf->b_ml.ml_locked = hp;
3676             buf->b_ml.ml_locked_low = low;
3677             buf->b_ml.ml_locked_high = high;
3678             buf->b_ml.ml_locked_lineadd = 0;
3679             buf->b_ml.ml_flags &= ~(ML_LOCKED_DIRTY | ML_LOCKED_POS);
3680             return hp;
3681         }
3682
3683         pp = (PTR_BL *)(dp);            /* must be pointer block */
3684         if (pp->pb_id != PTR_ID)
3685         {
3686             EMSG(_("E317: pointer block id wrong"));
3687             goto error_block;
3688         }
3689
3690         if ((top = ml_add_stack(buf)) < 0)      /* add new entry to stack */
3691             goto error_block;
3692         ip = &(buf->b_ml.ml_stack[top]);
3693         ip->ip_bnum = bnum;
3694         ip->ip_low = low;
3695         ip->ip_high = high;
3696         ip->ip_index = -1;              /* index not known yet */
3697
3698         dirty = FALSE;
3699         for (idx = 0; idx < (int)pp->pb_count; ++idx)
3700         {
3701             t = pp->pb_pointer[idx].pe_line_count;
3702             CHECK(t == 0, _("pe_line_count is zero"));
3703             if ((low += t) > lnum)
3704             {
3705                 ip->ip_index = idx;
3706                 bnum = pp->pb_pointer[idx].pe_bnum;
3707                 page_count = pp->pb_pointer[idx].pe_page_count;
3708                 high = low - 1;
3709                 low -= t;
3710
3711                 /*
3712                  * a negative block number may have been changed
3713                  */
3714                 if (bnum < 0)
3715                 {
3716                     bnum2 = mf_trans_del(mfp, bnum);
3717                     if (bnum != bnum2)
3718                     {
3719                         bnum = bnum2;
3720                         pp->pb_pointer[idx].pe_bnum = bnum;
3721                         dirty = TRUE;
3722                     }
3723                 }
3724
3725                 break;
3726             }
3727         }
3728         if (idx >= (int)pp->pb_count)       /* past the end: something wrong! */
3729         {
3730             if (lnum > buf->b_ml.ml_line_count)
3731                 EMSGN(_("E322: line number out of range: %ld past the end"),
3732                                               lnum - buf->b_ml.ml_line_count);
3733
3734             else
3735                 EMSGN(_("E323: line count wrong in block %ld"), bnum);
3736             goto error_block;
3737         }
3738         if (action == ML_DELETE)
3739         {
3740             pp->pb_pointer[idx].pe_line_count--;
3741             dirty = TRUE;
3742         }
3743         else if (action == ML_INSERT)
3744         {
3745             pp->pb_pointer[idx].pe_line_count++;
3746             dirty = TRUE;
3747         }
3748         mf_put(mfp, hp, dirty, FALSE);
3749     }
3750
3751 error_block:
3752     mf_put(mfp, hp, FALSE, FALSE);
3753 error_noblock:
3754     /*
3755      * If action is ML_DELETE or ML_INSERT we have to correct the tree for
3756      * the incremented/decremented line counts, because there won't be a line
3757      * inserted/deleted after all.
3758      */
3759     if (action == ML_DELETE)
3760         ml_lineadd(buf, 1);
3761     else if (action == ML_INSERT)
3762         ml_lineadd(buf, -1);
3763     buf->b_ml.ml_stack_top = 0;
3764     return NULL;
3765 }
3766
3767 /*
3768  * add an entry to the info pointer stack
3769  *
3770  * return -1 for failure, number of the new entry otherwise
3771  */
3772     static int
3773 ml_add_stack(buf)
3774     buf_T       *buf;
3775 {
3776     int         top;
3777     infoptr_T   *newstack;
3778
3779     top = buf->b_ml.ml_stack_top;
3780
3781     /* may have to increase the stack size */
3782     if (top == buf->b_ml.ml_stack_size)
3783     {
3784         CHECK(top > 0, _("Stack size increases")); /* more than 5 levels??? */
3785
3786         newstack = (infoptr_T *)alloc((unsigned)sizeof(infoptr_T) *
3787                                         (buf->b_ml.ml_stack_size + STACK_INCR));
3788         if (newstack == NULL)
3789             return -1;
3790         mch_memmove(newstack, buf->b_ml.ml_stack,
3791                                              (size_t)top * sizeof(infoptr_T));
3792         vim_free(buf->b_ml.ml_stack);
3793         buf->b_ml.ml_stack = newstack;
3794         buf->b_ml.ml_stack_size += STACK_INCR;
3795     }
3796
3797     buf->b_ml.ml_stack_top++;
3798     return top;
3799 }
3800
3801 /*
3802  * Update the pointer blocks on the stack for inserted/deleted lines.
3803  * The stack itself is also updated.
3804  *
3805  * When a insert/delete line action fails, the line is not inserted/deleted,
3806  * but the pointer blocks have already been updated. That is fixed here by
3807  * walking through the stack.
3808  *
3809  * Count is the number of lines added, negative if lines have been deleted.
3810  */
3811     static void
3812 ml_lineadd(buf, count)
3813     buf_T       *buf;
3814     int         count;
3815 {
3816     int         idx;
3817     infoptr_T   *ip;
3818     PTR_BL      *pp;
3819     memfile_T   *mfp = buf->b_ml.ml_mfp;
3820     bhdr_T      *hp;
3821
3822     for (idx = buf->b_ml.ml_stack_top - 1; idx >= 0; --idx)
3823     {
3824         ip = &(buf->b_ml.ml_stack[idx]);
3825         if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL)
3826             break;
3827         pp = (PTR_BL *)(hp->bh_data);   /* must be pointer block */
3828         if (pp->pb_id != PTR_ID)
3829         {
3830             mf_put(mfp, hp, FALSE, FALSE);
3831             EMSG(_("E317: pointer block id wrong 2"));
3832             break;
3833         }
3834         pp->pb_pointer[ip->ip_index].pe_line_count += count;
3835         ip->ip_high += count;
3836         mf_put(mfp, hp, TRUE, FALSE);
3837     }
3838 }
3839
3840 #if defined(HAVE_READLINK) || defined(PROTO)
3841 /*
3842  * Resolve a symlink in the last component of a file name.
3843  * Note that f_resolve() does it for every part of the path, we don't do that
3844  * here.
3845  * If it worked returns OK and the resolved link in "buf[MAXPATHL]".
3846  * Otherwise returns FAIL.
3847  */
3848     int
3849 resolve_symlink(fname, buf)
3850     char_u      *fname;
3851     char_u      *buf;
3852 {
3853     char_u      tmp[MAXPATHL];
3854     int         ret;
3855     int         depth = 0;
3856
3857     if (fname == NULL)
3858         return FAIL;
3859
3860     /* Put the result so far in tmp[], starting with the original name. */
3861     vim_strncpy(tmp, fname, MAXPATHL - 1);
3862
3863     for (;;)
3864     {
3865         /* Limit symlink depth to 100, catch recursive loops. */
3866         if (++depth == 100)
3867         {
3868             EMSG2(_("E773: Symlink loop for \"%s\""), fname);
3869             return FAIL;
3870         }
3871
3872         ret = readlink((char *)tmp, (char *)buf, MAXPATHL - 1);
3873         if (ret <= 0)
3874         {
3875             if (errno == EINVAL || errno == ENOENT)
3876             {
3877                 /* Found non-symlink or not existing file, stop here.
3878                  * When at the first level use the unmodified name, skip the
3879                  * call to vim_FullName(). */
3880                 if (depth == 1)
3881                     return FAIL;
3882
3883                 /* Use the resolved name in tmp[]. */
3884                 break;
3885             }
3886
3887             /* There must be some error reading links, use original name. */
3888             return FAIL;
3889         }
3890         buf[ret] = NUL;
3891
3892         /*
3893          * Check whether the symlink is relative or absolute.
3894          * If it's relative, build a new path based on the directory
3895          * portion of the filename (if any) and the path the symlink
3896          * points to.
3897          */
3898         if (mch_isFullName(buf))
3899             STRCPY(tmp, buf);
3900         else
3901         {
3902             char_u *tail;
3903
3904             tail = gettail(tmp);
3905             if (STRLEN(tail) + STRLEN(buf) >= MAXPATHL)
3906                 return FAIL;
3907             STRCPY(tail, buf);
3908         }
3909     }
3910
3911     /*
3912      * Try to resolve the full name of the file so that the swapfile name will
3913      * be consistent even when opening a relative symlink from different
3914      * working directories.
3915      */
3916     return vim_FullName(tmp, buf, MAXPATHL, TRUE);
3917 }
3918 #endif
3919
3920 /*
3921  * Make swap file name out of the file name and a directory name.
3922  * Returns pointer to allocated memory or NULL.
3923  */
3924     char_u *
3925 makeswapname(fname, ffname, buf, dir_name)
3926     char_u      *fname;
3927     char_u      *ffname UNUSED;
3928     buf_T       *buf;
3929     char_u      *dir_name;
3930 {
3931     char_u      *r, *s;
3932     char_u      *fname_res = fname;
3933 #ifdef HAVE_READLINK
3934     char_u      fname_buf[MAXPATHL];
3935 #endif
3936
3937 #if defined(UNIX) || defined(WIN3264)  /* Need _very_ long file names */
3938     s = dir_name + STRLEN(dir_name);
3939     if (after_pathsep(dir_name, s) && s[-1] == s[-2])
3940     {                          /* Ends with '//', Use Full path */
3941         r = NULL;
3942         if ((s = make_percent_swname(dir_name, fname)) != NULL)
3943         {
3944             r = modname(s, (char_u *)".swp", FALSE);
3945             vim_free(s);
3946         }
3947         return r;
3948     }
3949 #endif
3950
3951 #ifdef HAVE_READLINK
3952     /* Expand symlink in the file name, so that we put the swap file with the
3953      * actual file instead of with the symlink. */
3954     if (resolve_symlink(fname, fname_buf) == OK)
3955         fname_res = fname_buf;
3956 #endif
3957
3958     r = buf_modname(
3959 #ifdef SHORT_FNAME
3960             TRUE,
3961 #else
3962             (buf->b_p_sn || buf->b_shortname),
3963 #endif
3964 #ifdef RISCOS
3965             /* Avoid problems if fname has special chars, eg <Wimp$Scrap> */
3966             ffname,
3967 #else
3968             fname_res,
3969 #endif
3970             (char_u *)
3971 #if defined(VMS) || defined(RISCOS)
3972             "_swp",
3973 #else
3974             ".swp",
3975 #endif
3976 #ifdef SHORT_FNAME              /* always 8.3 file name */
3977             FALSE
3978 #else
3979             /* Prepend a '.' to the swap file name for the current directory. */
3980             dir_name[0] == '.' && dir_name[1] == NUL
3981 #endif
3982                );
3983     if (r == NULL)          /* out of memory */
3984         return NULL;
3985
3986     s = get_file_in_dir(r, dir_name);
3987     vim_free(r);
3988     return s;
3989 }
3990
3991 /*
3992  * Get file name to use for swap file or backup file.
3993  * Use the name of the edited file "fname" and an entry in the 'dir' or 'bdir'
3994  * option "dname".
3995  * - If "dname" is ".", return "fname" (swap file in dir of file).
3996  * - If "dname" starts with "./", insert "dname" in "fname" (swap file
3997  *   relative to dir of file).
3998  * - Otherwise, prepend "dname" to the tail of "fname" (swap file in specific
3999  *   dir).
4000  *
4001  * The return value is an allocated string and can be NULL.
4002  */
4003     char_u *
4004 get_file_in_dir(fname, dname)
4005     char_u  *fname;
4006     char_u  *dname;     /* don't use "dirname", it is a global for Alpha */
4007 {
4008     char_u      *t;
4009     char_u      *tail;
4010     char_u      *retval;
4011     int         save_char;
4012
4013     tail = gettail(fname);
4014
4015     if (dname[0] == '.' && dname[1] == NUL)
4016         retval = vim_strsave(fname);
4017     else if (dname[0] == '.' && vim_ispathsep(dname[1]))
4018     {
4019         if (tail == fname)          /* no path before file name */
4020             retval = concat_fnames(dname + 2, tail, TRUE);
4021         else
4022         {
4023             save_char = *tail;
4024             *tail = NUL;
4025             t = concat_fnames(fname, dname + 2, TRUE);
4026             *tail = save_char;
4027             if (t == NULL)          /* out of memory */
4028                 retval = NULL;
4029             else
4030             {
4031                 retval = concat_fnames(t, tail, TRUE);
4032                 vim_free(t);
4033             }
4034         }
4035     }
4036     else
4037         retval = concat_fnames(dname, tail, TRUE);
4038
4039     return retval;
4040 }
4041
4042 static void attention_message __ARGS((buf_T *buf, char_u *fname));
4043
4044 /*
4045  * Print the ATTENTION message: info about an existing swap file.
4046  */
4047     static void
4048 attention_message(buf, fname)
4049     buf_T   *buf;       /* buffer being edited */
4050     char_u  *fname;     /* swap file name */
4051 {
4052     struct stat st;
4053     time_t      x, sx;
4054     char        *p;
4055
4056     ++no_wait_return;
4057     (void)EMSG(_("E325: ATTENTION"));
4058     MSG_PUTS(_("\nFound a swap file by the name \""));
4059     msg_home_replace(fname);
4060     MSG_PUTS("\"\n");
4061     sx = swapfile_info(fname);
4062     MSG_PUTS(_("While opening file \""));
4063     msg_outtrans(buf->b_fname);
4064     MSG_PUTS("\"\n");
4065     if (mch_stat((char *)buf->b_fname, &st) != -1)
4066     {
4067         MSG_PUTS(_("             dated: "));
4068         x = st.st_mtime;    /* Manx C can't do &st.st_mtime */
4069         p = ctime(&x);                      /* includes '\n' */
4070         if (p == NULL)
4071             MSG_PUTS("(invalid)\n");
4072         else
4073             MSG_PUTS(p);
4074         if (sx != 0 && x > sx)
4075             MSG_PUTS(_("      NEWER than swap file!\n"));
4076     }
4077     /* Some of these messages are long to allow translation to
4078      * other languages. */
4079     MSG_PUTS(_("\n(1) Another program may be editing the same file.\n    If this is the case, be careful not to end up with two\n    different instances of the same file when making changes.\n"));
4080     MSG_PUTS(_("    Quit, or continue with caution.\n"));
4081     MSG_PUTS(_("\n(2) An edit session for this file crashed.\n"));
4082     MSG_PUTS(_("    If this is the case, use \":recover\" or \"vim -r "));
4083     msg_outtrans(buf->b_fname);
4084     MSG_PUTS(_("\"\n    to recover the changes (see \":help recovery\").\n"));
4085     MSG_PUTS(_("    If you did this already, delete the swap file \""));
4086     msg_outtrans(fname);
4087     MSG_PUTS(_("\"\n    to avoid this message.\n"));
4088     cmdline_row = msg_row;
4089     --no_wait_return;
4090 }
4091
4092 #ifdef FEAT_AUTOCMD
4093 static int do_swapexists __ARGS((buf_T *buf, char_u *fname));
4094
4095 /*
4096  * Trigger the SwapExists autocommands.
4097  * Returns a value for equivalent to do_dialog() (see below):
4098  * 0: still need to ask for a choice
4099  * 1: open read-only
4100  * 2: edit anyway
4101  * 3: recover
4102  * 4: delete it
4103  * 5: quit
4104  * 6: abort
4105  */
4106     static int
4107 do_swapexists(buf, fname)
4108     buf_T       *buf;
4109     char_u      *fname;
4110 {
4111     set_vim_var_string(VV_SWAPNAME, fname, -1);
4112     set_vim_var_string(VV_SWAPCHOICE, NULL, -1);
4113
4114     /* Trigger SwapExists autocommands with <afile> set to the file being
4115      * edited.  Disallow changing directory here. */
4116     ++allbuf_lock;
4117     apply_autocmds(EVENT_SWAPEXISTS, buf->b_fname, NULL, FALSE, NULL);
4118     --allbuf_lock;
4119
4120     set_vim_var_string(VV_SWAPNAME, NULL, -1);
4121
4122     switch (*get_vim_var_str(VV_SWAPCHOICE))
4123     {
4124         case 'o': return 1;
4125         case 'e': return 2;
4126         case 'r': return 3;
4127         case 'd': return 4;
4128         case 'q': return 5;
4129         case 'a': return 6;
4130     }
4131
4132     return 0;
4133 }
4134 #endif
4135
4136 /*
4137  * Find out what name to use for the swap file for buffer 'buf'.
4138  *
4139  * Several names are tried to find one that does not exist
4140  * Returns the name in allocated memory or NULL.
4141  *
4142  * Note: If BASENAMELEN is not correct, you will get error messages for
4143  *       not being able to open the swap or undo file
4144  * Note: May trigger SwapExists autocmd, pointers may change!
4145  */
4146     static char_u *
4147 findswapname(buf, dirp, old_fname)
4148     buf_T       *buf;
4149     char_u      **dirp;         /* pointer to list of directories */
4150     char_u      *old_fname;     /* don't give warning for this file name */
4151 {
4152     char_u      *fname;
4153     int         n;
4154     char_u      *dir_name;
4155 #ifdef AMIGA
4156     BPTR        fh;
4157 #endif
4158 #ifndef SHORT_FNAME
4159     int         r;
4160 #endif
4161
4162 #if !defined(SHORT_FNAME) \
4163                      && ((!defined(UNIX) && !defined(OS2)) || defined(ARCHIE))
4164 # define CREATE_DUMMY_FILE
4165     FILE        *dummyfd = NULL;
4166
4167     /*
4168      * If we start editing a new file, e.g. "test.doc", which resides on an
4169      * MSDOS compatible filesystem, it is possible that the file
4170      * "test.doc.swp" which we create will be exactly the same file. To avoid
4171      * this problem we temporarily create "test.doc".  Don't do this when the
4172      * check below for a 8.3 file name is used.
4173      */
4174     if (!(buf->b_p_sn || buf->b_shortname) && buf->b_fname != NULL
4175                                              && mch_getperm(buf->b_fname) < 0)
4176         dummyfd = mch_fopen((char *)buf->b_fname, "w");
4177 #endif
4178
4179     /*
4180      * Isolate a directory name from *dirp and put it in dir_name.
4181      * First allocate some memory to put the directory name in.
4182      */
4183     dir_name = alloc((unsigned)STRLEN(*dirp) + 1);
4184     if (dir_name != NULL)
4185         (void)copy_option_part(dirp, dir_name, 31000, ",");
4186
4187     /*
4188      * we try different names until we find one that does not exist yet
4189      */
4190     if (dir_name == NULL)           /* out of memory */
4191         fname = NULL;
4192     else
4193         fname = makeswapname(buf->b_fname, buf->b_ffname, buf, dir_name);
4194
4195     for (;;)
4196     {
4197         if (fname == NULL)      /* must be out of memory */
4198             break;
4199         if ((n = (int)STRLEN(fname)) == 0)      /* safety check */
4200         {
4201             vim_free(fname);
4202             fname = NULL;
4203             break;
4204         }
4205 #if (defined(UNIX) || defined(OS2)) && !defined(ARCHIE) && !defined(SHORT_FNAME)
4206 /*
4207  * Some systems have a MS-DOS compatible filesystem that use 8.3 character
4208  * file names. If this is the first try and the swap file name does not fit in
4209  * 8.3, detect if this is the case, set shortname and try again.
4210  */
4211         if (fname[n - 2] == 'w' && fname[n - 1] == 'p'
4212                                         && !(buf->b_p_sn || buf->b_shortname))
4213         {
4214             char_u          *tail;
4215             char_u          *fname2;
4216             struct stat     s1, s2;
4217             int             f1, f2;
4218             int             created1 = FALSE, created2 = FALSE;
4219             int             same = FALSE;
4220
4221             /*
4222              * Check if swapfile name does not fit in 8.3:
4223              * It either contains two dots, is longer than 8 chars, or starts
4224              * with a dot.
4225              */
4226             tail = gettail(buf->b_fname);
4227             if (       vim_strchr(tail, '.') != NULL
4228                     || STRLEN(tail) > (size_t)8
4229                     || *gettail(fname) == '.')
4230             {
4231                 fname2 = alloc(n + 2);
4232                 if (fname2 != NULL)
4233                 {
4234                     STRCPY(fname2, fname);
4235                     /* if fname == "xx.xx.swp",     fname2 = "xx.xx.swx"
4236                      * if fname == ".xx.swp",       fname2 = ".xx.swpx"
4237                      * if fname == "123456789.swp", fname2 = "12345678x.swp"
4238                      */
4239                     if (vim_strchr(tail, '.') != NULL)
4240                         fname2[n - 1] = 'x';
4241                     else if (*gettail(fname) == '.')
4242                     {
4243                         fname2[n] = 'x';
4244                         fname2[n + 1] = NUL;
4245                     }
4246                     else
4247                         fname2[n - 5] += 1;
4248                     /*
4249                      * may need to create the files to be able to use mch_stat()
4250                      */
4251                     f1 = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
4252                     if (f1 < 0)
4253                     {
4254                         f1 = mch_open_rw((char *)fname,
4255                                                O_RDWR|O_CREAT|O_EXCL|O_EXTRA);
4256 #if defined(OS2)
4257                         if (f1 < 0 && errno == ENOENT)
4258                             same = TRUE;
4259 #endif
4260                         created1 = TRUE;
4261                     }
4262                     if (f1 >= 0)
4263                     {
4264                         f2 = mch_open((char *)fname2, O_RDONLY | O_EXTRA, 0);
4265                         if (f2 < 0)
4266                         {
4267                             f2 = mch_open_rw((char *)fname2,
4268                                                O_RDWR|O_CREAT|O_EXCL|O_EXTRA);
4269                             created2 = TRUE;
4270                         }
4271                         if (f2 >= 0)
4272                         {
4273                             /*
4274                              * Both files exist now. If mch_stat() returns the
4275                              * same device and inode they are the same file.
4276                              */
4277                             if (mch_fstat(f1, &s1) != -1
4278                                     && mch_fstat(f2, &s2) != -1
4279                                     && s1.st_dev == s2.st_dev
4280                                     && s1.st_ino == s2.st_ino)
4281                                 same = TRUE;
4282                             close(f2);
4283                             if (created2)
4284                                 mch_remove(fname2);
4285                         }
4286                         close(f1);
4287                         if (created1)
4288                             mch_remove(fname);
4289                     }
4290                     vim_free(fname2);
4291                     if (same)
4292                     {
4293                         buf->b_shortname = TRUE;
4294                         vim_free(fname);
4295                         fname = makeswapname(buf->b_fname, buf->b_ffname,
4296                                                                buf, dir_name);
4297                         continue;       /* try again with b_shortname set */
4298                     }
4299                 }
4300             }
4301         }
4302 #endif
4303         /*
4304          * check if the swapfile already exists
4305          */
4306         if (mch_getperm(fname) < 0)     /* it does not exist */
4307         {
4308 #ifdef HAVE_LSTAT
4309             struct stat sb;
4310
4311             /*
4312              * Extra security check: When a swap file is a symbolic link, this
4313              * is most likely a symlink attack.
4314              */
4315             if (mch_lstat((char *)fname, &sb) < 0)
4316 #else
4317 # ifdef AMIGA
4318             fh = Open((UBYTE *)fname, (long)MODE_NEWFILE);
4319             /*
4320              * on the Amiga mch_getperm() will return -1 when the file exists
4321              * but is being used by another program. This happens if you edit
4322              * a file twice.
4323              */
4324             if (fh != (BPTR)NULL)       /* can open file, OK */
4325             {
4326                 Close(fh);
4327                 mch_remove(fname);
4328                 break;
4329             }
4330             if (IoErr() != ERROR_OBJECT_IN_USE
4331                                             && IoErr() != ERROR_OBJECT_EXISTS)
4332 # endif
4333 #endif
4334                 break;
4335         }
4336
4337         /*
4338          * A file name equal to old_fname is OK to use.
4339          */
4340         if (old_fname != NULL && fnamecmp(fname, old_fname) == 0)
4341             break;
4342
4343         /*
4344          * get here when file already exists
4345          */
4346         if (fname[n - 2] == 'w' && fname[n - 1] == 'p') /* first try */
4347         {
4348 #ifndef SHORT_FNAME
4349             /*
4350              * on MS-DOS compatible filesystems (e.g. messydos) file.doc.swp
4351              * and file.doc are the same file. To guess if this problem is
4352              * present try if file.doc.swx exists. If it does, we set
4353              * buf->b_shortname and try file_doc.swp (dots replaced by
4354              * underscores for this file), and try again. If it doesn't we
4355              * assume that "file.doc.swp" already exists.
4356              */
4357             if (!(buf->b_p_sn || buf->b_shortname))     /* not tried yet */
4358             {
4359                 fname[n - 1] = 'x';
4360                 r = mch_getperm(fname);         /* try "file.swx" */
4361                 fname[n - 1] = 'p';
4362                 if (r >= 0)                 /* "file.swx" seems to exist */
4363                 {
4364                     buf->b_shortname = TRUE;
4365                     vim_free(fname);
4366                     fname = makeswapname(buf->b_fname, buf->b_ffname,
4367                                                                buf, dir_name);
4368                     continue;       /* try again with '.' replaced with '_' */
4369                 }
4370             }
4371 #endif
4372             /*
4373              * If we get here the ".swp" file really exists.
4374              * Give an error message, unless recovering, no file name, we are
4375              * viewing a help file or when the path of the file is different
4376              * (happens when all .swp files are in one directory).
4377              */
4378             if (!recoverymode && buf->b_fname != NULL
4379                                 && !buf->b_help && !(buf->b_flags & BF_DUMMY))
4380             {
4381                 int             fd;
4382                 struct block0   b0;
4383                 int             differ = FALSE;
4384
4385                 /*
4386                  * Try to read block 0 from the swap file to get the original
4387                  * file name (and inode number).
4388                  */
4389                 fd = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
4390                 if (fd >= 0)
4391                 {
4392                     if (read(fd, (char *)&b0, sizeof(b0)) == sizeof(b0))
4393                     {
4394                         /*
4395                          * If the swapfile has the same directory as the
4396                          * buffer don't compare the directory names, they can
4397                          * have a different mountpoint.
4398                          */
4399                         if (b0.b0_flags & B0_SAME_DIR)
4400                         {
4401                             if (fnamecmp(gettail(buf->b_ffname),
4402                                                    gettail(b0.b0_fname)) != 0
4403                                     || !same_directory(fname, buf->b_ffname))
4404                             {
4405 #ifdef CHECK_INODE
4406                                 /* Symlinks may point to the same file even
4407                                  * when the name differs, need to check the
4408                                  * inode too. */
4409                                 expand_env(b0.b0_fname, NameBuff, MAXPATHL);
4410                                 if (fnamecmp_ino(buf->b_ffname, NameBuff,
4411                                                      char_to_long(b0.b0_ino)))
4412 #endif
4413                                     differ = TRUE;
4414                             }
4415                         }
4416                         else
4417                         {
4418                             /*
4419                              * The name in the swap file may be
4420                              * "~user/path/file".  Expand it first.
4421                              */
4422                             expand_env(b0.b0_fname, NameBuff, MAXPATHL);
4423 #ifdef CHECK_INODE
4424                             if (fnamecmp_ino(buf->b_ffname, NameBuff,
4425                                                      char_to_long(b0.b0_ino)))
4426                                 differ = TRUE;
4427 #else
4428                             if (fnamecmp(NameBuff, buf->b_ffname) != 0)
4429                                 differ = TRUE;
4430 #endif
4431                         }
4432                     }
4433                     close(fd);
4434                 }
4435 #ifdef RISCOS
4436                 else
4437                     /* Can't open swap file, though it does exist.
4438                      * Assume that the user is editing two files with
4439                      * the same name in different directories. No error.
4440                      */
4441                     differ = TRUE;
4442 #endif
4443
4444                 /* give the ATTENTION message when there is an old swap file
4445                  * for the current file, and the buffer was not recovered. */
4446                 if (differ == FALSE && !(curbuf->b_flags & BF_RECOVERED)
4447                         && vim_strchr(p_shm, SHM_ATTENTION) == NULL)
4448                 {
4449 #if defined(HAS_SWAP_EXISTS_ACTION)
4450                     int         choice = 0;
4451 #endif
4452 #ifdef CREATE_DUMMY_FILE
4453                     int         did_use_dummy = FALSE;
4454
4455                     /* Avoid getting a warning for the file being created
4456                      * outside of Vim, it was created at the start of this
4457                      * function.  Delete the file now, because Vim might exit
4458                      * here if the window is closed. */
4459                     if (dummyfd != NULL)
4460                     {
4461                         fclose(dummyfd);
4462                         dummyfd = NULL;
4463                         mch_remove(buf->b_fname);
4464                         did_use_dummy = TRUE;
4465                     }
4466 #endif
4467
4468 #if (defined(UNIX) || defined(__EMX__) || defined(VMS)) && (defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG))
4469                     process_still_running = FALSE;
4470 #endif
4471 #ifdef FEAT_AUTOCMD
4472                     /*
4473                      * If there is an SwapExists autocommand and we can handle
4474                      * the response, trigger it.  It may return 0 to ask the
4475                      * user anyway.
4476                      */
4477                     if (swap_exists_action != SEA_NONE
4478                             && has_autocmd(EVENT_SWAPEXISTS, buf->b_fname, buf))
4479                         choice = do_swapexists(buf, fname);
4480
4481                     if (choice == 0)
4482 #endif
4483                     {
4484 #ifdef FEAT_GUI
4485                         /* If we are supposed to start the GUI but it wasn't
4486                          * completely started yet, start it now.  This makes
4487                          * the messages displayed in the Vim window when
4488                          * loading a session from the .gvimrc file. */
4489                         if (gui.starting && !gui.in_use)
4490                             gui_start();
4491 #endif
4492                         /* Show info about the existing swap file. */
4493                         attention_message(buf, fname);
4494
4495                         /* We don't want a 'q' typed at the more-prompt
4496                          * interrupt loading a file. */
4497                         got_int = FALSE;
4498                     }
4499
4500 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
4501                     if (swap_exists_action != SEA_NONE && choice == 0)
4502                     {
4503                         char_u  *name;
4504
4505                         name = alloc((unsigned)(STRLEN(fname)
4506                                 + STRLEN(_("Swap file \""))
4507                                 + STRLEN(_("\" already exists!")) + 5));
4508                         if (name != NULL)
4509                         {
4510                             STRCPY(name, _("Swap file \""));
4511                             home_replace(NULL, fname, name + STRLEN(name),
4512                                                                   1000, TRUE);
4513                             STRCAT(name, _("\" already exists!"));
4514                         }
4515                         choice = do_dialog(VIM_WARNING,
4516                                     (char_u *)_("VIM - ATTENTION"),
4517                                     name == NULL
4518                                         ?  (char_u *)_("Swap file already exists!")
4519                                         : name,
4520 # if defined(UNIX) || defined(__EMX__) || defined(VMS)
4521                                     process_still_running
4522                                         ? (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover\n&Quit\n&Abort") :
4523 # endif
4524                                         (char_u *)_("&Open Read-Only\n&Edit anyway\n&Recover\n&Delete it\n&Quit\n&Abort"), 1, NULL);
4525
4526 # if defined(UNIX) || defined(__EMX__) || defined(VMS)
4527                         if (process_still_running && choice >= 4)
4528                             choice++;   /* Skip missing "Delete it" button */
4529 # endif
4530                         vim_free(name);
4531
4532                         /* pretend screen didn't scroll, need redraw anyway */
4533                         msg_scrolled = 0;
4534                         redraw_all_later(NOT_VALID);
4535                     }
4536 #endif
4537
4538 #if defined(HAS_SWAP_EXISTS_ACTION)
4539                     if (choice > 0)
4540                     {
4541                         switch (choice)
4542                         {
4543                             case 1:
4544                                 buf->b_p_ro = TRUE;
4545                                 break;
4546                             case 2:
4547                                 break;
4548                             case 3:
4549                                 swap_exists_action = SEA_RECOVER;
4550                                 break;
4551                             case 4:
4552                                 mch_remove(fname);
4553                                 break;
4554                             case 5:
4555                                 swap_exists_action = SEA_QUIT;
4556                                 break;
4557                             case 6:
4558                                 swap_exists_action = SEA_QUIT;
4559                                 got_int = TRUE;
4560                                 break;
4561                         }
4562
4563                         /* If the file was deleted this fname can be used. */
4564                         if (mch_getperm(fname) < 0)
4565                             break;
4566                     }
4567                     else
4568 #endif
4569                     {
4570                         MSG_PUTS("\n");
4571                         if (msg_silent == 0)
4572                             /* call wait_return() later */
4573                             need_wait_return = TRUE;
4574                     }
4575
4576 #ifdef CREATE_DUMMY_FILE
4577                     /* Going to try another name, need the dummy file again. */
4578                     if (did_use_dummy)
4579                         dummyfd = mch_fopen((char *)buf->b_fname, "w");
4580 #endif
4581                 }
4582             }
4583         }
4584
4585         /*
4586          * Change the ".swp" extension to find another file that can be used.
4587          * First decrement the last char: ".swo", ".swn", etc.
4588          * If that still isn't enough decrement the last but one char: ".svz"
4589          * Can happen when editing many "No Name" buffers.
4590          */
4591         if (fname[n - 1] == 'a')        /* ".s?a" */
4592         {
4593             if (fname[n - 2] == 'a')    /* ".saa": tried enough, give up */
4594             {
4595                 EMSG(_("E326: Too many swap files found"));
4596                 vim_free(fname);
4597                 fname = NULL;
4598                 break;
4599             }
4600             --fname[n - 2];             /* ".svz", ".suz", etc. */
4601             fname[n - 1] = 'z' + 1;
4602         }
4603         --fname[n - 1];                 /* ".swo", ".swn", etc. */
4604     }
4605
4606     vim_free(dir_name);
4607 #ifdef CREATE_DUMMY_FILE
4608     if (dummyfd != NULL)        /* file has been created temporarily */
4609     {
4610         fclose(dummyfd);
4611         mch_remove(buf->b_fname);
4612     }
4613 #endif
4614     return fname;
4615 }
4616
4617     static int
4618 b0_magic_wrong(b0p)
4619     ZERO_BL *b0p;
4620 {
4621     return (b0p->b0_magic_long != (long)B0_MAGIC_LONG
4622             || b0p->b0_magic_int != (int)B0_MAGIC_INT
4623             || b0p->b0_magic_short != (short)B0_MAGIC_SHORT
4624             || b0p->b0_magic_char != B0_MAGIC_CHAR);
4625 }
4626
4627 #ifdef CHECK_INODE
4628 /*
4629  * Compare current file name with file name from swap file.
4630  * Try to use inode numbers when possible.
4631  * Return non-zero when files are different.
4632  *
4633  * When comparing file names a few things have to be taken into consideration:
4634  * - When working over a network the full path of a file depends on the host.
4635  *   We check the inode number if possible.  It is not 100% reliable though,
4636  *   because the device number cannot be used over a network.
4637  * - When a file does not exist yet (editing a new file) there is no inode
4638  *   number.
4639  * - The file name in a swap file may not be valid on the current host.  The
4640  *   "~user" form is used whenever possible to avoid this.
4641  *
4642  * This is getting complicated, let's make a table:
4643  *
4644  *              ino_c  ino_s  fname_c  fname_s  differ =
4645  *
4646  * both files exist -> compare inode numbers:
4647  *              != 0   != 0     X        X      ino_c != ino_s
4648  *
4649  * inode number(s) unknown, file names available -> compare file names
4650  *              == 0    X       OK       OK     fname_c != fname_s
4651  *               X     == 0     OK       OK     fname_c != fname_s
4652  *
4653  * current file doesn't exist, file for swap file exist, file name(s) not
4654  * available -> probably different
4655  *              == 0   != 0    FAIL      X      TRUE
4656  *              == 0   != 0     X       FAIL    TRUE
4657  *
4658  * current file exists, inode for swap unknown, file name(s) not
4659  * available -> probably different
4660  *              != 0   == 0    FAIL      X      TRUE
4661  *              != 0   == 0     X       FAIL    TRUE
4662  *
4663  * current file doesn't exist, inode for swap unknown, one file name not
4664  * available -> probably different
4665  *              == 0   == 0    FAIL      OK     TRUE
4666  *              == 0   == 0     OK      FAIL    TRUE
4667  *
4668  * current file doesn't exist, inode for swap unknown, both file names not
4669  * available -> probably same file
4670  *              == 0   == 0    FAIL     FAIL    FALSE
4671  *
4672  * Note that when the ino_t is 64 bits, only the last 32 will be used.  This
4673  * can't be changed without making the block 0 incompatible with 32 bit
4674  * versions.
4675  */
4676
4677     static int
4678 fnamecmp_ino(fname_c, fname_s, ino_block0)
4679     char_u      *fname_c;           /* current file name */
4680     char_u      *fname_s;           /* file name from swap file */
4681     long        ino_block0;
4682 {
4683     struct stat st;
4684     ino_t       ino_c = 0;          /* ino of current file */
4685     ino_t       ino_s;              /* ino of file from swap file */
4686     char_u      buf_c[MAXPATHL];    /* full path of fname_c */
4687     char_u      buf_s[MAXPATHL];    /* full path of fname_s */
4688     int         retval_c;           /* flag: buf_c valid */
4689     int         retval_s;           /* flag: buf_s valid */
4690
4691     if (mch_stat((char *)fname_c, &st) == 0)
4692         ino_c = (ino_t)st.st_ino;
4693
4694     /*
4695      * First we try to get the inode from the file name, because the inode in
4696      * the swap file may be outdated.  If that fails (e.g. this path is not
4697      * valid on this machine), use the inode from block 0.
4698      */
4699     if (mch_stat((char *)fname_s, &st) == 0)
4700         ino_s = (ino_t)st.st_ino;
4701     else
4702         ino_s = (ino_t)ino_block0;
4703
4704     if (ino_c && ino_s)
4705         return (ino_c != ino_s);
4706
4707     /*
4708      * One of the inode numbers is unknown, try a forced vim_FullName() and
4709      * compare the file names.
4710      */
4711     retval_c = vim_FullName(fname_c, buf_c, MAXPATHL, TRUE);
4712     retval_s = vim_FullName(fname_s, buf_s, MAXPATHL, TRUE);
4713     if (retval_c == OK && retval_s == OK)
4714         return (STRCMP(buf_c, buf_s) != 0);
4715
4716     /*
4717      * Can't compare inodes or file names, guess that the files are different,
4718      * unless both appear not to exist at all.
4719      */
4720     if (ino_s == 0 && ino_c == 0 && retval_c == FAIL && retval_s == FAIL)
4721         return FALSE;
4722     return TRUE;
4723 }
4724 #endif /* CHECK_INODE */
4725
4726 /*
4727  * Move a long integer into a four byte character array.
4728  * Used for machine independency in block zero.
4729  */
4730     static void
4731 long_to_char(n, s)
4732     long    n;
4733     char_u  *s;
4734 {
4735     s[0] = (char_u)(n & 0xff);
4736     n = (unsigned)n >> 8;
4737     s[1] = (char_u)(n & 0xff);
4738     n = (unsigned)n >> 8;
4739     s[2] = (char_u)(n & 0xff);
4740     n = (unsigned)n >> 8;
4741     s[3] = (char_u)(n & 0xff);
4742 }
4743
4744     static long
4745 char_to_long(s)
4746     char_u  *s;
4747 {
4748     long    retval;
4749
4750     retval = s[3];
4751     retval <<= 8;
4752     retval |= s[2];
4753     retval <<= 8;
4754     retval |= s[1];
4755     retval <<= 8;
4756     retval |= s[0];
4757
4758     return retval;
4759 }
4760
4761 /*
4762  * Set the flags in the first block of the swap file:
4763  * - file is modified or not: buf->b_changed
4764  * - 'fileformat'
4765  * - 'fileencoding'
4766  */
4767     void
4768 ml_setflags(buf)
4769     buf_T       *buf;
4770 {
4771     bhdr_T      *hp;
4772     ZERO_BL     *b0p;
4773
4774     if (!buf->b_ml.ml_mfp)
4775         return;
4776     for (hp = buf->b_ml.ml_mfp->mf_used_last; hp != NULL; hp = hp->bh_prev)
4777     {
4778         if (hp->bh_bnum == 0)
4779         {
4780             b0p = (ZERO_BL *)(hp->bh_data);
4781             b0p->b0_dirty = buf->b_changed ? B0_DIRTY : 0;
4782             b0p->b0_flags = (b0p->b0_flags & ~B0_FF_MASK)
4783                                                   | (get_fileformat(buf) + 1);
4784 #ifdef FEAT_MBYTE
4785             add_b0_fenc(b0p, buf);
4786 #endif
4787             hp->bh_flags |= BH_DIRTY;
4788             mf_sync(buf->b_ml.ml_mfp, MFS_ZERO);
4789             break;
4790         }
4791     }
4792 }
4793
4794 #if defined(FEAT_CRYPT) || defined(PROTO)
4795 /*
4796  * If "data" points to a data block encrypt the text in it and return a copy
4797  * in allocated memory.  Return NULL when out of memory.
4798  * Otherwise return "data".
4799  */
4800     char_u *
4801 ml_encrypt_data(mfp, data, offset, size)
4802     memfile_T   *mfp;
4803     char_u      *data;
4804     off_t       offset;
4805     unsigned    size;
4806 {
4807     DATA_BL     *dp = (DATA_BL *)data;
4808     char_u      *head_end;
4809     char_u      *text_start;
4810     char_u      *new_data;
4811     int         text_len;
4812
4813     if (dp->db_id != DATA_ID)
4814         return data;
4815
4816     new_data = (char_u *)alloc(size);
4817     if (new_data == NULL)
4818         return NULL;
4819     head_end = (char_u *)(&dp->db_index[dp->db_line_count]);
4820     text_start = (char_u *)dp + dp->db_txt_start;
4821     text_len = size - dp->db_txt_start;
4822
4823     /* Copy the header and the text. */
4824     mch_memmove(new_data, dp, head_end - (char_u *)dp);
4825
4826     /* Encrypt the text. */
4827     crypt_push_state();
4828     ml_crypt_prepare(mfp, offset, FALSE);
4829     crypt_encode(text_start, text_len, new_data + dp->db_txt_start);
4830     crypt_pop_state();
4831
4832     /* Clear the gap. */
4833     if (head_end < text_start)
4834         vim_memset(new_data + (head_end - data), 0, text_start - head_end);
4835
4836     return new_data;
4837 }
4838
4839 /*
4840  * Decrypt the text in "data" if it points to a data block.
4841  */
4842     void
4843 ml_decrypt_data(mfp, data, offset, size)
4844     memfile_T   *mfp;
4845     char_u      *data;
4846     off_t       offset;
4847     unsigned    size;
4848 {
4849     DATA_BL     *dp = (DATA_BL *)data;
4850     char_u      *head_end;
4851     char_u      *text_start;
4852     int         text_len;
4853
4854     if (dp->db_id == DATA_ID)
4855     {
4856         head_end = (char_u *)(&dp->db_index[dp->db_line_count]);
4857         text_start = (char_u *)dp + dp->db_txt_start;
4858         text_len = dp->db_txt_end - dp->db_txt_start;
4859
4860         if (head_end > text_start || dp->db_txt_start > size
4861                                                      || dp->db_txt_end > size)
4862             return;  /* data was messed up */
4863
4864         /* Decrypt the text in place. */
4865         crypt_push_state();
4866         ml_crypt_prepare(mfp, offset, TRUE);
4867         crypt_decode(text_start, text_len);
4868         crypt_pop_state();
4869     }
4870 }
4871
4872 /*
4873  * Prepare for encryption/decryption, using the key, seed and offset.
4874  */
4875     static void
4876 ml_crypt_prepare(mfp, offset, reading)
4877     memfile_T   *mfp;
4878     off_t       offset;
4879     int         reading;
4880 {
4881     buf_T       *buf = mfp->mf_buffer;
4882     char_u      salt[50];
4883     int         method;
4884     char_u      *key;
4885     char_u      *seed;
4886
4887     if (reading && mfp->mf_old_key != NULL)
4888     {
4889         /* Reading back blocks with the previous key/method/seed. */
4890         method = mfp->mf_old_cm;
4891         key = mfp->mf_old_key;
4892         seed = mfp->mf_old_seed;
4893     }
4894     else
4895     {
4896         method = get_crypt_method(buf);
4897         key = buf->b_p_key;
4898         seed = mfp->mf_seed;
4899     }
4900
4901     use_crypt_method = method;  /* select pkzip or blowfish */
4902     if (method == 0)
4903     {
4904         vim_snprintf((char *)salt, sizeof(salt), "%s%ld", key, (long)offset);
4905         crypt_init_keys(salt);
4906     }
4907     else
4908     {
4909         /* Using blowfish, add salt and seed. We use the byte offset of the
4910          * block for the salt. */
4911         vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset);
4912         bf_key_init(key, salt, (int)STRLEN(salt));
4913         bf_ofb_init(seed, MF_SEED_LEN);
4914     }
4915 }
4916
4917 #endif
4918
4919
4920 #if defined(FEAT_BYTEOFF) || defined(PROTO)
4921
4922 #define MLCS_MAXL 800   /* max no of lines in chunk */
4923 #define MLCS_MINL 400   /* should be half of MLCS_MAXL */
4924
4925 /*
4926  * Keep information for finding byte offset of a line, updtype may be one of:
4927  * ML_CHNK_ADDLINE: Add len to parent chunk, possibly splitting it
4928  *         Careful: ML_CHNK_ADDLINE may cause ml_find_line() to be called.
4929  * ML_CHNK_DELLINE: Subtract len from parent chunk, possibly deleting it
4930  * ML_CHNK_UPDLINE: Add len to parent chunk, as a signed entity.
4931  */
4932     static void
4933 ml_updatechunk(buf, line, len, updtype)
4934     buf_T       *buf;
4935     linenr_T    line;
4936     long        len;
4937     int         updtype;
4938 {
4939     static buf_T        *ml_upd_lastbuf = NULL;
4940     static linenr_T     ml_upd_lastline;
4941     static linenr_T     ml_upd_lastcurline;
4942     static int          ml_upd_lastcurix;
4943
4944     linenr_T            curline = ml_upd_lastcurline;
4945     int                 curix = ml_upd_lastcurix;
4946     long                size;
4947     chunksize_T         *curchnk;
4948     int                 rest;
4949     bhdr_T              *hp;
4950     DATA_BL             *dp;
4951
4952     if (buf->b_ml.ml_usedchunks == -1 || len == 0)
4953         return;
4954     if (buf->b_ml.ml_chunksize == NULL)
4955     {
4956         buf->b_ml.ml_chunksize = (chunksize_T *)
4957                                   alloc((unsigned)sizeof(chunksize_T) * 100);
4958         if (buf->b_ml.ml_chunksize == NULL)
4959         {
4960             buf->b_ml.ml_usedchunks = -1;
4961             return;
4962         }
4963         buf->b_ml.ml_numchunks = 100;
4964         buf->b_ml.ml_usedchunks = 1;
4965         buf->b_ml.ml_chunksize[0].mlcs_numlines = 1;
4966         buf->b_ml.ml_chunksize[0].mlcs_totalsize = 1;
4967     }
4968
4969     if (updtype == ML_CHNK_UPDLINE && buf->b_ml.ml_line_count == 1)
4970     {
4971         /*
4972          * First line in empty buffer from ml_flush_line() -- reset
4973          */
4974         buf->b_ml.ml_usedchunks = 1;
4975         buf->b_ml.ml_chunksize[0].mlcs_numlines = 1;
4976         buf->b_ml.ml_chunksize[0].mlcs_totalsize =
4977                                   (long)STRLEN(buf->b_ml.ml_line_ptr) + 1;
4978         return;
4979     }
4980
4981     /*
4982      * Find chunk that our line belongs to, curline will be at start of the
4983      * chunk.
4984      */
4985     if (buf != ml_upd_lastbuf || line != ml_upd_lastline + 1
4986             || updtype != ML_CHNK_ADDLINE)
4987     {
4988         for (curline = 1, curix = 0;
4989              curix < buf->b_ml.ml_usedchunks - 1
4990              && line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines;
4991              curix++)
4992         {
4993             curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
4994         }
4995     }
4996     else if (line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines
4997                  && curix < buf->b_ml.ml_usedchunks - 1)
4998     {
4999         /* Adjust cached curix & curline */
5000         curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
5001         curix++;
5002     }
5003     curchnk = buf->b_ml.ml_chunksize + curix;
5004
5005     if (updtype == ML_CHNK_DELLINE)
5006         len = -len;
5007     curchnk->mlcs_totalsize += len;
5008     if (updtype == ML_CHNK_ADDLINE)
5009     {
5010         curchnk->mlcs_numlines++;
5011
5012         /* May resize here so we don't have to do it in both cases below */
5013         if (buf->b_ml.ml_usedchunks + 1 >= buf->b_ml.ml_numchunks)
5014         {
5015             buf->b_ml.ml_numchunks = buf->b_ml.ml_numchunks * 3 / 2;
5016             buf->b_ml.ml_chunksize = (chunksize_T *)
5017                 vim_realloc(buf->b_ml.ml_chunksize,
5018                             sizeof(chunksize_T) * buf->b_ml.ml_numchunks);
5019             if (buf->b_ml.ml_chunksize == NULL)
5020             {
5021                 /* Hmmmm, Give up on offset for this buffer */
5022                 buf->b_ml.ml_usedchunks = -1;
5023                 return;
5024             }
5025         }
5026
5027         if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MAXL)
5028         {
5029             int     count;          /* number of entries in block */
5030             int     idx;
5031             int     text_end;
5032             int     linecnt;
5033
5034             mch_memmove(buf->b_ml.ml_chunksize + curix + 1,
5035                         buf->b_ml.ml_chunksize + curix,
5036                         (buf->b_ml.ml_usedchunks - curix) *
5037                         sizeof(chunksize_T));
5038             /* Compute length of first half of lines in the split chunk */
5039             size = 0;
5040             linecnt = 0;
5041             while (curline < buf->b_ml.ml_line_count
5042                         && linecnt < MLCS_MINL)
5043             {
5044                 if ((hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
5045                 {
5046                     buf->b_ml.ml_usedchunks = -1;
5047                     return;
5048                 }
5049                 dp = (DATA_BL *)(hp->bh_data);
5050                 count = (long)(buf->b_ml.ml_locked_high) -
5051                         (long)(buf->b_ml.ml_locked_low) + 1;
5052                 idx = curline - buf->b_ml.ml_locked_low;
5053                 curline = buf->b_ml.ml_locked_high + 1;
5054                 if (idx == 0)/* first line in block, text at the end */
5055                     text_end = dp->db_txt_end;
5056                 else
5057                     text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
5058                 /* Compute index of last line to use in this MEMLINE */
5059                 rest = count - idx;
5060                 if (linecnt + rest > MLCS_MINL)
5061                 {
5062                     idx += MLCS_MINL - linecnt - 1;
5063                     linecnt = MLCS_MINL;
5064                 }
5065                 else
5066                 {
5067                     idx = count - 1;
5068                     linecnt += rest;
5069                 }
5070                 size += text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
5071             }
5072             buf->b_ml.ml_chunksize[curix].mlcs_numlines = linecnt;
5073             buf->b_ml.ml_chunksize[curix + 1].mlcs_numlines -= linecnt;
5074             buf->b_ml.ml_chunksize[curix].mlcs_totalsize = size;
5075             buf->b_ml.ml_chunksize[curix + 1].mlcs_totalsize -= size;
5076             buf->b_ml.ml_usedchunks++;
5077             ml_upd_lastbuf = NULL;   /* Force recalc of curix & curline */
5078             return;
5079         }
5080         else if (buf->b_ml.ml_chunksize[curix].mlcs_numlines >= MLCS_MINL
5081                      && curix == buf->b_ml.ml_usedchunks - 1
5082                      && buf->b_ml.ml_line_count - line <= 1)
5083         {
5084             /*
5085              * We are in the last chunk and it is cheap to crate a new one
5086              * after this. Do it now to avoid the loop above later on
5087              */
5088             curchnk = buf->b_ml.ml_chunksize + curix + 1;
5089             buf->b_ml.ml_usedchunks++;
5090             if (line == buf->b_ml.ml_line_count)
5091             {
5092                 curchnk->mlcs_numlines = 0;
5093                 curchnk->mlcs_totalsize = 0;
5094             }
5095             else
5096             {
5097                 /*
5098                  * Line is just prior to last, move count for last
5099                  * This is the common case  when loading a new file
5100                  */
5101                 hp = ml_find_line(buf, buf->b_ml.ml_line_count, ML_FIND);
5102                 if (hp == NULL)
5103                 {
5104                     buf->b_ml.ml_usedchunks = -1;
5105                     return;
5106                 }
5107                 dp = (DATA_BL *)(hp->bh_data);
5108                 if (dp->db_line_count == 1)
5109                     rest = dp->db_txt_end - dp->db_txt_start;
5110                 else
5111                     rest =
5112                         ((dp->db_index[dp->db_line_count - 2]) & DB_INDEX_MASK)
5113                         - dp->db_txt_start;
5114                 curchnk->mlcs_totalsize = rest;
5115                 curchnk->mlcs_numlines = 1;
5116                 curchnk[-1].mlcs_totalsize -= rest;
5117                 curchnk[-1].mlcs_numlines -= 1;
5118             }
5119         }
5120     }
5121     else if (updtype == ML_CHNK_DELLINE)
5122     {
5123         curchnk->mlcs_numlines--;
5124         ml_upd_lastbuf = NULL;   /* Force recalc of curix & curline */
5125         if (curix < (buf->b_ml.ml_usedchunks - 1)
5126                 && (curchnk->mlcs_numlines + curchnk[1].mlcs_numlines)
5127                    <= MLCS_MINL)
5128         {
5129             curix++;
5130             curchnk = buf->b_ml.ml_chunksize + curix;
5131         }
5132         else if (curix == 0 && curchnk->mlcs_numlines <= 0)
5133         {
5134             buf->b_ml.ml_usedchunks--;
5135             mch_memmove(buf->b_ml.ml_chunksize, buf->b_ml.ml_chunksize + 1,
5136                         buf->b_ml.ml_usedchunks * sizeof(chunksize_T));
5137             return;
5138         }
5139         else if (curix == 0 || (curchnk->mlcs_numlines > 10
5140                     && (curchnk->mlcs_numlines + curchnk[-1].mlcs_numlines)
5141                        > MLCS_MINL))
5142         {
5143             return;
5144         }
5145
5146         /* Collapse chunks */
5147         curchnk[-1].mlcs_numlines += curchnk->mlcs_numlines;
5148         curchnk[-1].mlcs_totalsize += curchnk->mlcs_totalsize;
5149         buf->b_ml.ml_usedchunks--;
5150         if (curix < buf->b_ml.ml_usedchunks)
5151         {
5152             mch_memmove(buf->b_ml.ml_chunksize + curix,
5153                         buf->b_ml.ml_chunksize + curix + 1,
5154                         (buf->b_ml.ml_usedchunks - curix) *
5155                         sizeof(chunksize_T));
5156         }
5157         return;
5158     }
5159     ml_upd_lastbuf = buf;
5160     ml_upd_lastline = line;
5161     ml_upd_lastcurline = curline;
5162     ml_upd_lastcurix = curix;
5163 }
5164
5165 /*
5166  * Find offset for line or line with offset.
5167  * Find line with offset if "lnum" is 0; return remaining offset in offp
5168  * Find offset of line if "lnum" > 0
5169  * return -1 if information is not available
5170  */
5171     long
5172 ml_find_line_or_offset(buf, lnum, offp)
5173     buf_T       *buf;
5174     linenr_T    lnum;
5175     long        *offp;
5176 {
5177     linenr_T    curline;
5178     int         curix;
5179     long        size;
5180     bhdr_T      *hp;
5181     DATA_BL     *dp;
5182     int         count;          /* number of entries in block */
5183     int         idx;
5184     int         start_idx;
5185     int         text_end;
5186     long        offset;
5187     int         len;
5188     int         ffdos = (get_fileformat(buf) == EOL_DOS);
5189     int         extra = 0;
5190
5191     /* take care of cached line first */
5192     ml_flush_line(curbuf);
5193
5194     if (buf->b_ml.ml_usedchunks == -1
5195             || buf->b_ml.ml_chunksize == NULL
5196             || lnum < 0)
5197         return -1;
5198
5199     if (offp == NULL)
5200         offset = 0;
5201     else
5202         offset = *offp;
5203     if (lnum == 0 && offset <= 0)
5204         return 1;   /* Not a "find offset" and offset 0 _must_ be in line 1 */
5205     /*
5206      * Find the last chunk before the one containing our line. Last chunk is
5207      * special because it will never qualify
5208      */
5209     curline = 1;
5210     curix = size = 0;
5211     while (curix < buf->b_ml.ml_usedchunks - 1
5212             && ((lnum != 0
5213              && lnum >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines)
5214                 || (offset != 0
5215                && offset > size + buf->b_ml.ml_chunksize[curix].mlcs_totalsize
5216                       + ffdos * buf->b_ml.ml_chunksize[curix].mlcs_numlines)))
5217     {
5218         curline += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
5219         size += buf->b_ml.ml_chunksize[curix].mlcs_totalsize;
5220         if (offset && ffdos)
5221             size += buf->b_ml.ml_chunksize[curix].mlcs_numlines;
5222         curix++;
5223     }
5224
5225     while ((lnum != 0 && curline < lnum) || (offset != 0 && size < offset))
5226     {
5227         if (curline > buf->b_ml.ml_line_count
5228                 || (hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
5229             return -1;
5230         dp = (DATA_BL *)(hp->bh_data);
5231         count = (long)(buf->b_ml.ml_locked_high) -
5232                 (long)(buf->b_ml.ml_locked_low) + 1;
5233         start_idx = idx = curline - buf->b_ml.ml_locked_low;
5234         if (idx == 0)/* first line in block, text at the end */
5235             text_end = dp->db_txt_end;
5236         else
5237             text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
5238         /* Compute index of last line to use in this MEMLINE */
5239         if (lnum != 0)
5240         {
5241             if (curline + (count - idx) >= lnum)
5242                 idx += lnum - curline - 1;
5243             else
5244                 idx = count - 1;
5245         }
5246         else
5247         {
5248             extra = 0;
5249             while (offset >= size
5250                        + text_end - (int)((dp->db_index[idx]) & DB_INDEX_MASK)
5251                                                                       + ffdos)
5252             {
5253                 if (ffdos)
5254                     size++;
5255                 if (idx == count - 1)
5256                 {
5257                     extra = 1;
5258                     break;
5259                 }
5260                 idx++;
5261             }
5262         }
5263         len = text_end - ((dp->db_index[idx]) & DB_INDEX_MASK);
5264         size += len;
5265         if (offset != 0 && size >= offset)
5266         {
5267             if (size + ffdos == offset)
5268                 *offp = 0;
5269             else if (idx == start_idx)
5270                 *offp = offset - size + len;
5271             else
5272                 *offp = offset - size + len
5273                      - (text_end - ((dp->db_index[idx - 1]) & DB_INDEX_MASK));
5274             curline += idx - start_idx + extra;
5275             if (curline > buf->b_ml.ml_line_count)
5276                 return -1;      /* exactly one byte beyond the end */
5277             return curline;
5278         }
5279         curline = buf->b_ml.ml_locked_high + 1;
5280     }
5281
5282     if (lnum != 0)
5283     {
5284         /* Count extra CR characters. */
5285         if (ffdos)
5286             size += lnum - 1;
5287
5288         /* Don't count the last line break if 'bin' and 'noeol'. */
5289         if (buf->b_p_bin && !buf->b_p_eol)
5290             size -= ffdos + 1;
5291     }
5292
5293     return size;
5294 }
5295
5296 /*
5297  * Goto byte in buffer with offset 'cnt'.
5298  */
5299     void
5300 goto_byte(cnt)
5301     long        cnt;
5302 {
5303     long        boff = cnt;
5304     linenr_T    lnum;
5305
5306     ml_flush_line(curbuf);      /* cached line may be dirty */
5307     setpcmark();
5308     if (boff)
5309         --boff;
5310     lnum = ml_find_line_or_offset(curbuf, (linenr_T)0, &boff);
5311     if (lnum < 1)       /* past the end */
5312     {
5313         curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
5314         curwin->w_curswant = MAXCOL;
5315         coladvance((colnr_T)MAXCOL);
5316     }
5317     else
5318     {
5319         curwin->w_cursor.lnum = lnum;
5320         curwin->w_cursor.col = (colnr_T)boff;
5321 # ifdef FEAT_VIRTUALEDIT
5322         curwin->w_cursor.coladd = 0;
5323 # endif
5324         curwin->w_set_curswant = TRUE;
5325     }
5326     check_cursor();
5327
5328 # ifdef FEAT_MBYTE
5329     /* Make sure the cursor is on the first byte of a multi-byte char. */
5330     if (has_mbyte)
5331         mb_adjust_cursor();
5332 # endif
5333 }
5334 #endif