|
Karsten Hopp |
92a436 |
To: vim_dev@googlegroups.com
|
|
Karsten Hopp |
92a436 |
Subject: Patch 7.4.730
|
|
Karsten Hopp |
92a436 |
Fcc: outbox
|
|
Karsten Hopp |
92a436 |
From: Bram Moolenaar <Bram@moolenaar.net>
|
|
Karsten Hopp |
92a436 |
Mime-Version: 1.0
|
|
Karsten Hopp |
92a436 |
Content-Type: text/plain; charset=UTF-8
|
|
Karsten Hopp |
92a436 |
Content-Transfer-Encoding: 8bit
|
|
Karsten Hopp |
92a436 |
------------
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
Patch 7.4.730
|
|
Karsten Hopp |
92a436 |
Problem: When setting the crypt key and using a swap file, text may be
|
|
Karsten Hopp |
92a436 |
encrypted twice or unencrypted text remains in the swap file.
|
|
Karsten Hopp |
92a436 |
(Issue 369)
|
|
Karsten Hopp |
92a436 |
Solution: Call ml_preserve() before re-encrypting. Set correct index for
|
|
Karsten Hopp |
92a436 |
next pointer block.
|
|
Karsten Hopp |
92a436 |
Files: src/memfile.c, src/memline.c, src/proto/memline.pro, src/option.c
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
*** ../vim-7.4.729/src/memfile.c 2015-02-27 18:25:10.820179062 +0100
|
|
Karsten Hopp |
92a436 |
--- src/memfile.c 2015-06-09 18:20:03.021860562 +0200
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 811,816 ****
|
|
Karsten Hopp |
92a436 |
--- 811,818 ----
|
|
Karsten Hopp |
92a436 |
*
|
|
Karsten Hopp |
92a436 |
* Return the block header to the caller, including the memory block, so
|
|
Karsten Hopp |
92a436 |
* it can be re-used. Make sure the page_count is right.
|
|
Karsten Hopp |
92a436 |
+ *
|
|
Karsten Hopp |
92a436 |
+ * Returns NULL if no block is released.
|
|
Karsten Hopp |
92a436 |
*/
|
|
Karsten Hopp |
92a436 |
static bhdr_T *
|
|
Karsten Hopp |
92a436 |
mf_release(mfp, page_count)
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 1219,1225 ****
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
/*
|
|
Karsten Hopp |
92a436 |
! * Lookup a translation from the trans lists and delete the entry
|
|
Karsten Hopp |
92a436 |
*
|
|
Karsten Hopp |
92a436 |
* Return the positive new number when found, the old number when not found
|
|
Karsten Hopp |
92a436 |
*/
|
|
Karsten Hopp |
92a436 |
--- 1221,1227 ----
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
/*
|
|
Karsten Hopp |
92a436 |
! * Lookup a translation from the trans lists and delete the entry.
|
|
Karsten Hopp |
92a436 |
*
|
|
Karsten Hopp |
92a436 |
* Return the positive new number when found, the old number when not found
|
|
Karsten Hopp |
92a436 |
*/
|
|
Karsten Hopp |
92a436 |
*** ../vim-7.4.729/src/memline.c 2015-03-31 13:33:00.797524914 +0200
|
|
Karsten Hopp |
92a436 |
--- src/memline.c 2015-06-09 18:24:46.186622422 +0200
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 488,494 ****
|
|
Karsten Hopp |
92a436 |
ml_set_crypt_key(buf, old_key, old_cm)
|
|
Karsten Hopp |
92a436 |
buf_T *buf;
|
|
Karsten Hopp |
92a436 |
char_u *old_key;
|
|
Karsten Hopp |
92a436 |
! int old_cm;
|
|
Karsten Hopp |
92a436 |
{
|
|
Karsten Hopp |
92a436 |
memfile_T *mfp = buf->b_ml.ml_mfp;
|
|
Karsten Hopp |
92a436 |
bhdr_T *hp;
|
|
Karsten Hopp |
92a436 |
--- 488,494 ----
|
|
Karsten Hopp |
92a436 |
ml_set_crypt_key(buf, old_key, old_cm)
|
|
Karsten Hopp |
92a436 |
buf_T *buf;
|
|
Karsten Hopp |
92a436 |
char_u *old_key;
|
|
Karsten Hopp |
92a436 |
! char_u *old_cm;
|
|
Karsten Hopp |
92a436 |
{
|
|
Karsten Hopp |
92a436 |
memfile_T *mfp = buf->b_ml.ml_mfp;
|
|
Karsten Hopp |
92a436 |
bhdr_T *hp;
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 500,514 ****
|
|
Karsten Hopp |
92a436 |
DATA_BL *dp;
|
|
Karsten Hopp |
92a436 |
blocknr_T bnum;
|
|
Karsten Hopp |
92a436 |
int top;
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
if (mfp == NULL)
|
|
Karsten Hopp |
92a436 |
return; /* no memfile yet, nothing to do */
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
/* Set the key, method and seed to be used for reading, these must be the
|
|
Karsten Hopp |
92a436 |
* old values. */
|
|
Karsten Hopp |
92a436 |
mfp->mf_old_key = old_key;
|
|
Karsten Hopp |
92a436 |
! mfp->mf_old_cm = old_cm;
|
|
Karsten Hopp |
92a436 |
! if (old_cm > 0)
|
|
Karsten Hopp |
92a436 |
mch_memmove(mfp->mf_old_seed, mfp->mf_seed, MF_SEED_LEN);
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
/* Update block 0 with the crypt flag and may set a new seed. */
|
|
Karsten Hopp |
92a436 |
--- 500,529 ----
|
|
Karsten Hopp |
92a436 |
DATA_BL *dp;
|
|
Karsten Hopp |
92a436 |
blocknr_T bnum;
|
|
Karsten Hopp |
92a436 |
int top;
|
|
Karsten Hopp |
92a436 |
+ int old_method;
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
if (mfp == NULL)
|
|
Karsten Hopp |
92a436 |
return; /* no memfile yet, nothing to do */
|
|
Karsten Hopp |
92a436 |
+ old_method = crypt_method_nr_from_name(old_cm);
|
|
Karsten Hopp |
92a436 |
+
|
|
Karsten Hopp |
92a436 |
+ /* First make sure the swapfile is in a consistent state, using the old
|
|
Karsten Hopp |
92a436 |
+ * key and method. */
|
|
Karsten Hopp |
92a436 |
+ {
|
|
Karsten Hopp |
92a436 |
+ char_u *new_key = buf->b_p_key;
|
|
Karsten Hopp |
92a436 |
+ char_u *new_buf_cm = buf->b_p_cm;
|
|
Karsten Hopp |
92a436 |
+
|
|
Karsten Hopp |
92a436 |
+ buf->b_p_key = old_key;
|
|
Karsten Hopp |
92a436 |
+ buf->b_p_cm = old_cm;
|
|
Karsten Hopp |
92a436 |
+ ml_preserve(buf, FALSE);
|
|
Karsten Hopp |
92a436 |
+ buf->b_p_key = new_key;
|
|
Karsten Hopp |
92a436 |
+ buf->b_p_cm = new_buf_cm;
|
|
Karsten Hopp |
92a436 |
+ }
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
/* Set the key, method and seed to be used for reading, these must be the
|
|
Karsten Hopp |
92a436 |
* old values. */
|
|
Karsten Hopp |
92a436 |
mfp->mf_old_key = old_key;
|
|
Karsten Hopp |
92a436 |
! mfp->mf_old_cm = old_method;
|
|
Karsten Hopp |
92a436 |
! if (old_method > 0 && *old_key != NUL)
|
|
Karsten Hopp |
92a436 |
mch_memmove(mfp->mf_old_seed, mfp->mf_seed, MF_SEED_LEN);
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
/* Update block 0 with the crypt flag and may set a new seed. */
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 561,568 ****
|
|
Karsten Hopp |
92a436 |
{
|
|
Karsten Hopp |
92a436 |
if (pp->pb_pointer[idx].pe_bnum < 0)
|
|
Karsten Hopp |
92a436 |
{
|
|
Karsten Hopp |
92a436 |
! /* Skip data block with negative block number. */
|
|
Karsten Hopp |
92a436 |
! ++idx; /* get same block again for next index */
|
|
Karsten Hopp |
92a436 |
continue;
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
--- 576,585 ----
|
|
Karsten Hopp |
92a436 |
{
|
|
Karsten Hopp |
92a436 |
if (pp->pb_pointer[idx].pe_bnum < 0)
|
|
Karsten Hopp |
92a436 |
{
|
|
Karsten Hopp |
92a436 |
! /* Skip data block with negative block number.
|
|
Karsten Hopp |
92a436 |
! * Should not happen, because of the ml_preserve()
|
|
Karsten Hopp |
92a436 |
! * above. Get same block again for next index. */
|
|
Karsten Hopp |
92a436 |
! ++idx;
|
|
Karsten Hopp |
92a436 |
continue;
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 579,584 ****
|
|
Karsten Hopp |
92a436 |
--- 596,602 ----
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
bnum = pp->pb_pointer[idx].pe_bnum;
|
|
Karsten Hopp |
92a436 |
page_count = pp->pb_pointer[idx].pe_page_count;
|
|
Karsten Hopp |
92a436 |
+ idx = 0;
|
|
Karsten Hopp |
92a436 |
continue;
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 605,610 ****
|
|
Karsten Hopp |
92a436 |
--- 623,630 ----
|
|
Karsten Hopp |
92a436 |
idx = ip->ip_index + 1; /* go to next index */
|
|
Karsten Hopp |
92a436 |
page_count = 1;
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
+ if (hp != NULL)
|
|
Karsten Hopp |
92a436 |
+ mf_put(mfp, hp, FALSE, FALSE); /* release previous block */
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
if (error > 0)
|
|
Karsten Hopp |
92a436 |
EMSG(_("E843: Error while updating swap file crypt"));
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 4859,4864 ****
|
|
Karsten Hopp |
92a436 |
--- 4879,4888 ----
|
|
Karsten Hopp |
92a436 |
if (dp->db_id != DATA_ID)
|
|
Karsten Hopp |
92a436 |
return data;
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
+ state = ml_crypt_prepare(mfp, offset, FALSE);
|
|
Karsten Hopp |
92a436 |
+ if (state == NULL)
|
|
Karsten Hopp |
92a436 |
+ return data;
|
|
Karsten Hopp |
92a436 |
+
|
|
Karsten Hopp |
92a436 |
new_data = (char_u *)alloc(size);
|
|
Karsten Hopp |
92a436 |
if (new_data == NULL)
|
|
Karsten Hopp |
92a436 |
return NULL;
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 4870,4876 ****
|
|
Karsten Hopp |
92a436 |
mch_memmove(new_data, dp, head_end - (char_u *)dp);
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
/* Encrypt the text. */
|
|
Karsten Hopp |
92a436 |
- state = ml_crypt_prepare(mfp, offset, FALSE);
|
|
Karsten Hopp |
92a436 |
crypt_encode(state, text_start, text_len, new_data + dp->db_txt_start);
|
|
Karsten Hopp |
92a436 |
crypt_free_state(state);
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
--- 4894,4899 ----
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 4882,4888 ****
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
/*
|
|
Karsten Hopp |
92a436 |
! * Decrypt the text in "data" if it points to a data block.
|
|
Karsten Hopp |
92a436 |
*/
|
|
Karsten Hopp |
92a436 |
void
|
|
Karsten Hopp |
92a436 |
ml_decrypt_data(mfp, data, offset, size)
|
|
Karsten Hopp |
92a436 |
--- 4905,4911 ----
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
/*
|
|
Karsten Hopp |
92a436 |
! * Decrypt the text in "data" if it points to an encrypted data block.
|
|
Karsten Hopp |
92a436 |
*/
|
|
Karsten Hopp |
92a436 |
void
|
|
Karsten Hopp |
92a436 |
ml_decrypt_data(mfp, data, offset, size)
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 4907,4916 ****
|
|
Karsten Hopp |
92a436 |
|| dp->db_txt_end > size)
|
|
Karsten Hopp |
92a436 |
return; /* data was messed up */
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
- /* Decrypt the text in place. */
|
|
Karsten Hopp |
92a436 |
state = ml_crypt_prepare(mfp, offset, TRUE);
|
|
Karsten Hopp |
92a436 |
! crypt_decode_inplace(state, text_start, text_len);
|
|
Karsten Hopp |
92a436 |
! crypt_free_state(state);
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
--- 4930,4942 ----
|
|
Karsten Hopp |
92a436 |
|| dp->db_txt_end > size)
|
|
Karsten Hopp |
92a436 |
return; /* data was messed up */
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
state = ml_crypt_prepare(mfp, offset, TRUE);
|
|
Karsten Hopp |
92a436 |
! if (state != NULL)
|
|
Karsten Hopp |
92a436 |
! {
|
|
Karsten Hopp |
92a436 |
! /* Decrypt the text in place. */
|
|
Karsten Hopp |
92a436 |
! crypt_decode_inplace(state, text_start, text_len);
|
|
Karsten Hopp |
92a436 |
! crypt_free_state(state);
|
|
Karsten Hopp |
92a436 |
! }
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 4943,4948 ****
|
|
Karsten Hopp |
92a436 |
--- 4969,4976 ----
|
|
Karsten Hopp |
92a436 |
key = buf->b_p_key;
|
|
Karsten Hopp |
92a436 |
seed = mfp->mf_seed;
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
+ if (*key == NUL)
|
|
Karsten Hopp |
92a436 |
+ return NULL;
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
if (method_nr == CRYPT_M_ZIP)
|
|
Karsten Hopp |
92a436 |
{
|
|
Karsten Hopp |
92a436 |
*** ../vim-7.4.729/src/proto/memline.pro 2013-08-10 13:37:18.000000000 +0200
|
|
Karsten Hopp |
92a436 |
--- src/proto/memline.pro 2015-06-09 16:30:03.989599819 +0200
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 1,6 ****
|
|
Karsten Hopp |
92a436 |
/* memline.c */
|
|
Karsten Hopp |
92a436 |
int ml_open __ARGS((buf_T *buf));
|
|
Karsten Hopp |
92a436 |
! void ml_set_crypt_key __ARGS((buf_T *buf, char_u *old_key, int old_cm));
|
|
Karsten Hopp |
92a436 |
void ml_setname __ARGS((buf_T *buf));
|
|
Karsten Hopp |
92a436 |
void ml_open_files __ARGS((void));
|
|
Karsten Hopp |
92a436 |
void ml_open_file __ARGS((buf_T *buf));
|
|
Karsten Hopp |
92a436 |
--- 1,6 ----
|
|
Karsten Hopp |
92a436 |
/* memline.c */
|
|
Karsten Hopp |
92a436 |
int ml_open __ARGS((buf_T *buf));
|
|
Karsten Hopp |
92a436 |
! void ml_set_crypt_key __ARGS((buf_T *buf, char_u *old_key, char_u *old_cm));
|
|
Karsten Hopp |
92a436 |
void ml_setname __ARGS((buf_T *buf));
|
|
Karsten Hopp |
92a436 |
void ml_open_files __ARGS((void));
|
|
Karsten Hopp |
92a436 |
void ml_open_file __ARGS((buf_T *buf));
|
|
Karsten Hopp |
92a436 |
*** ../vim-7.4.729/src/option.c 2015-04-21 19:10:41.311067930 +0200
|
|
Karsten Hopp |
92a436 |
--- src/option.c 2015-06-09 16:30:37.209226314 +0200
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 6163,6169 ****
|
|
Karsten Hopp |
92a436 |
# endif
|
|
Karsten Hopp |
92a436 |
if (STRCMP(curbuf->b_p_key, oldval) != 0)
|
|
Karsten Hopp |
92a436 |
/* Need to update the swapfile. */
|
|
Karsten Hopp |
92a436 |
! ml_set_crypt_key(curbuf, oldval, crypt_get_method_nr(curbuf));
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
else if (gvarp == &p_cm)
|
|
Karsten Hopp |
92a436 |
--- 6163,6170 ----
|
|
Karsten Hopp |
92a436 |
# endif
|
|
Karsten Hopp |
92a436 |
if (STRCMP(curbuf->b_p_key, oldval) != 0)
|
|
Karsten Hopp |
92a436 |
/* Need to update the swapfile. */
|
|
Karsten Hopp |
92a436 |
! ml_set_crypt_key(curbuf, oldval,
|
|
Karsten Hopp |
92a436 |
! *curbuf->b_p_cm == NUL ? p_cm : curbuf->b_p_cm);
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
else if (gvarp == &p_cm)
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 6207,6214 ****
|
|
Karsten Hopp |
92a436 |
else
|
|
Karsten Hopp |
92a436 |
p = curbuf->b_p_cm;
|
|
Karsten Hopp |
92a436 |
if (STRCMP(s, p) != 0)
|
|
Karsten Hopp |
92a436 |
! ml_set_crypt_key(curbuf, curbuf->b_p_key,
|
|
Karsten Hopp |
92a436 |
! crypt_method_nr_from_name(s));
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
/* If the global value changes need to update the swapfile for all
|
|
Karsten Hopp |
92a436 |
* buffers using that value. */
|
|
Karsten Hopp |
92a436 |
--- 6208,6214 ----
|
|
Karsten Hopp |
92a436 |
else
|
|
Karsten Hopp |
92a436 |
p = curbuf->b_p_cm;
|
|
Karsten Hopp |
92a436 |
if (STRCMP(s, p) != 0)
|
|
Karsten Hopp |
92a436 |
! ml_set_crypt_key(curbuf, curbuf->b_p_key, s);
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
/* If the global value changes need to update the swapfile for all
|
|
Karsten Hopp |
92a436 |
* buffers using that value. */
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 6218,6225 ****
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
|
|
Karsten Hopp |
92a436 |
if (buf != curbuf && *buf->b_p_cm == NUL)
|
|
Karsten Hopp |
92a436 |
! ml_set_crypt_key(buf, buf->b_p_key,
|
|
Karsten Hopp |
92a436 |
! crypt_method_nr_from_name(oldval));
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
--- 6218,6224 ----
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
|
|
Karsten Hopp |
92a436 |
if (buf != curbuf && *buf->b_p_cm == NUL)
|
|
Karsten Hopp |
92a436 |
! ml_set_crypt_key(buf, buf->b_p_key, oldval);
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
}
|
|
Karsten Hopp |
92a436 |
*** ../vim-7.4.729/src/version.c 2015-05-14 05:55:59.138935575 +0200
|
|
Karsten Hopp |
92a436 |
--- src/version.c 2015-06-09 18:21:27.252897234 +0200
|
|
Karsten Hopp |
92a436 |
***************
|
|
Karsten Hopp |
92a436 |
*** 743,744 ****
|
|
Karsten Hopp |
92a436 |
--- 743,746 ----
|
|
Karsten Hopp |
92a436 |
{ /* Add new patch number below this line */
|
|
Karsten Hopp |
92a436 |
+ /**/
|
|
Karsten Hopp |
92a436 |
+ 730,
|
|
Karsten Hopp |
92a436 |
/**/
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
--
|
|
Karsten Hopp |
92a436 |
From "know your smileys":
|
|
Karsten Hopp |
92a436 |
:-X My lips are sealed
|
|
Karsten Hopp |
92a436 |
|
|
Karsten Hopp |
92a436 |
/// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
|
|
Karsten Hopp |
92a436 |
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
|
|
Karsten Hopp |
92a436 |
\\\ an exciting new programming language -- http://www.Zimbu.org ///
|
|
Karsten Hopp |
92a436 |
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
|