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