diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-07-14 22:43:10 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-07-14 22:43:10 +0000 |
commit | 59a1f3045073c92c661035f87bdf7e28099358eb (patch) | |
tree | d69a4bcc1059e2bf9ed2e6bb59d26d408a16fac1 | |
parent | fb79a2e2cfe33002398f1898c26d8e4f341db006 (diff) | |
download | busybox-w32-59a1f3045073c92c661035f87bdf7e28099358eb.tar.gz busybox-w32-59a1f3045073c92c661035f87bdf7e28099358eb.tar.bz2 busybox-w32-59a1f3045073c92c661035f87bdf7e28099358eb.zip |
vi: make status line less confusing when we open non-readable files,
require rood to use w! when saving non-writable files.
Patch by Natanael Copa <natanael.copa@gmail.com>
update_ro_status - 73 +73
edit_file 819 822 +3
colon 3440 3425 -15
.rodata 128090 128058 -32
file_insert 288 235 -53
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/3 up/down: 76/-100) Total: -24 bytes
text data bss dec hex filename
673344 2740 13968 690052 a8784 busybox_old
673320 2740 13968 690028 a876c busybox_unstripped
-rw-r--r-- | editors/vi.c | 99 |
1 files changed, 40 insertions, 59 deletions
diff --git a/editors/vi.c b/editors/vi.c index 01d45e50e..fda29acfb 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -229,7 +229,12 @@ static int mysleep(int); // sleep for 'h' 1/100 seconds | |||
229 | static char readit(void); // read (maybe cursor) key from stdin | 229 | static char readit(void); // read (maybe cursor) key from stdin |
230 | static char get_one_char(void); // read 1 char from stdin | 230 | static char get_one_char(void); // read 1 char from stdin |
231 | static int file_size(const char *); // what is the byte size of "fn" | 231 | static int file_size(const char *); // what is the byte size of "fn" |
232 | static int file_insert(char *, char *, int); | 232 | static int file_insert(char *, char *); |
233 | #if ENABLE_FEATURE_VI_READONLY | ||
234 | static void update_ro_status(const char *); | ||
235 | #else | ||
236 | static ALWAYS_INLINE void update_ro_status(const char *name) {} | ||
237 | #endif | ||
233 | static int file_write(char *, char *, char *); | 238 | static int file_write(char *, char *, char *); |
234 | static void place_cursor(int, int, int); | 239 | static void place_cursor(int, int, int); |
235 | static void screen_erase(void); | 240 | static void screen_erase(void); |
@@ -419,8 +424,9 @@ static void edit_file(char * fn) | |||
419 | new_text(size); // get a text[] buffer | 424 | new_text(size); // get a text[] buffer |
420 | screenbegin = dot = end = text; | 425 | screenbegin = dot = end = text; |
421 | if (fn != 0) { | 426 | if (fn != 0) { |
422 | ch = file_insert(fn, text, cnt); | 427 | ch = file_insert(fn, text); |
423 | } | 428 | update_ro_status(fn); |
429 | } | ||
424 | if (ch < 1) { | 430 | if (ch < 1) { |
425 | char_insert(text, '\n'); // start empty buf with dummy line | 431 | char_insert(text, '\n'); // start empty buf with dummy line |
426 | } | 432 | } |
@@ -654,7 +660,6 @@ static void colon(char * buf) | |||
654 | char *fn, cmd[MAX_LINELEN], args[MAX_LINELEN]; | 660 | char *fn, cmd[MAX_LINELEN], args[MAX_LINELEN]; |
655 | int i, l, li, ch, b, e; | 661 | int i, l, li, ch, b, e; |
656 | int useforce = FALSE, forced = FALSE; | 662 | int useforce = FALSE, forced = FALSE; |
657 | struct stat st_buf; | ||
658 | 663 | ||
659 | // :3154 // if (-e line 3154) goto it else stay put | 664 | // :3154 // if (-e line 3154) goto it else stay put |
660 | // :4,33w! foo // write a portion of buffer to file "foo" | 665 | // :4,33w! foo // write a portion of buffer to file "foo" |
@@ -758,6 +763,7 @@ static void colon(char * buf) | |||
758 | dot_skip_over_ws(); | 763 | dot_skip_over_ws(); |
759 | } else if (strncasecmp(cmd, "edit", i) == 0) { // Edit a file | 764 | } else if (strncasecmp(cmd, "edit", i) == 0) { // Edit a file |
760 | int sr; | 765 | int sr; |
766 | struct stat st_buf; | ||
761 | sr= 0; | 767 | sr= 0; |
762 | // don't edit, if the current file has been modified | 768 | // don't edit, if the current file has been modified |
763 | if (file_modified && ! useforce) { | 769 | if (file_modified && ! useforce) { |
@@ -809,7 +815,8 @@ static void colon(char * buf) | |||
809 | screenbegin = dot = end = text; | 815 | screenbegin = dot = end = text; |
810 | 816 | ||
811 | // insert new file | 817 | // insert new file |
812 | ch = file_insert(fn, text, file_size(fn)); | 818 | ch = file_insert(fn, text); |
819 | update_ro_status(fn); | ||
813 | 820 | ||
814 | if (ch < 1) { | 821 | if (ch < 1) { |
815 | // start empty buf with dummy line | 822 | // start empty buf with dummy line |
@@ -937,25 +944,15 @@ static void colon(char * buf) | |||
937 | // read after current line- unless user said ":0r foo" | 944 | // read after current line- unless user said ":0r foo" |
938 | if (b != 0) | 945 | if (b != 0) |
939 | q = next_line(q); | 946 | q = next_line(q); |
940 | #if ENABLE_FEATURE_VI_READONLY | 947 | ch = file_insert(fn, q); |
941 | l = readonly; // remember current files' status | ||
942 | #endif | ||
943 | ch = file_insert(fn, q, file_size(fn)); | ||
944 | #if ENABLE_FEATURE_VI_READONLY | ||
945 | readonly = l; | ||
946 | #endif | ||
947 | if (ch < 0) | 948 | if (ch < 0) |
948 | goto vc1; // nothing was inserted | 949 | goto vc1; // nothing was inserted |
949 | // how many lines in text[]? | 950 | // how many lines in text[]? |
950 | li = count_lines(q, q + ch - 1); | 951 | li = count_lines(q, q + ch - 1); |
951 | psb("\"%s\"" | 952 | psb("\"%s\"" |
952 | #if ENABLE_FEATURE_VI_READONLY | 953 | USE_FEATURE_VI_READONLY("%s") |
953 | "%s" | ||
954 | #endif | ||
955 | " %dL, %dC", fn, | 954 | " %dL, %dC", fn, |
956 | #if ENABLE_FEATURE_VI_READONLY | 955 | USE_FEATURE_VI_READONLY(((vi_readonly || readonly) ? " [Read only]" : ""),) |
957 | ((vi_readonly || readonly) ? " [Read only]" : ""), | ||
958 | #endif | ||
959 | li, ch); | 956 | li, ch); |
960 | if (ch > 0) { | 957 | if (ch > 0) { |
961 | // if the insert is before "dot" then we need to update | 958 | // if the insert is before "dot" then we need to update |
@@ -2399,37 +2396,22 @@ static char *get_input_line(const char * prompt) // get input line- use "status | |||
2399 | static int file_size(const char * fn) // what is the byte size of "fn" | 2396 | static int file_size(const char * fn) // what is the byte size of "fn" |
2400 | { | 2397 | { |
2401 | struct stat st_buf; | 2398 | struct stat st_buf; |
2402 | int cnt, sr; | 2399 | int cnt; |
2403 | 2400 | ||
2404 | if (!fn || !fn[0]) | ||
2405 | return -1; | ||
2406 | cnt = -1; | 2401 | cnt = -1; |
2407 | sr = stat(fn, &st_buf); // see if file exists | 2402 | if (fn && fn[0] && stat(fn, &st_buf) == 0) // see if file exists |
2408 | if (sr >= 0) { | ||
2409 | cnt = (int) st_buf.st_size; | 2403 | cnt = (int) st_buf.st_size; |
2410 | } | ||
2411 | return cnt; | 2404 | return cnt; |
2412 | } | 2405 | } |
2413 | 2406 | ||
2414 | static int file_insert(char * fn, char * p, int size) | 2407 | static int file_insert(char * fn, char * p) |
2415 | { | 2408 | { |
2416 | int fd, cnt; | 2409 | int cnt = -1; |
2417 | 2410 | int fd, size; | |
2418 | cnt = -1; | 2411 | |
2419 | #if ENABLE_FEATURE_VI_READONLY | 2412 | size = file_size(fn); |
2420 | readonly = FALSE; | ||
2421 | #endif | ||
2422 | if (!fn || !fn[0]) { | ||
2423 | psbs("No filename given"); | ||
2424 | goto fi0; | ||
2425 | } | ||
2426 | if (size == 0) { | ||
2427 | // OK- this is just a no-op | ||
2428 | cnt = 0; | ||
2429 | goto fi0; | ||
2430 | } | ||
2431 | if (size < 0) { | 2413 | if (size < 0) { |
2432 | psbs("Trying to insert a negative number (%d) of characters", size); | 2414 | psbs("File does not exist"); |
2433 | goto fi0; | 2415 | goto fi0; |
2434 | } | 2416 | } |
2435 | if (p < text || p > end) { | 2417 | if (p < text || p > end) { |
@@ -2437,25 +2419,11 @@ static int file_insert(char * fn, char * p, int size) | |||
2437 | goto fi0; | 2419 | goto fi0; |
2438 | } | 2420 | } |
2439 | 2421 | ||
2440 | // see if we can open the file | 2422 | // read file to buffer |
2441 | #if ENABLE_FEATURE_VI_READONLY | 2423 | fd = open(fn, O_RDONLY); |
2442 | if (vi_readonly) goto fi1; // do not try write-mode | ||
2443 | #endif | ||
2444 | fd = open(fn, O_RDWR); // assume read & write | ||
2445 | if (fd < 0) { | 2424 | if (fd < 0) { |
2446 | // could not open for writing- maybe file is read only | 2425 | psbs("\"%s\" %s", fn, "cannot open file"); |
2447 | #if ENABLE_FEATURE_VI_READONLY | 2426 | goto fi0; |
2448 | fi1: | ||
2449 | #endif | ||
2450 | fd = open(fn, O_RDONLY); // try read-only | ||
2451 | if (fd < 0) { | ||
2452 | psbs("\"%s\" %s", fn, "cannot open file"); | ||
2453 | goto fi0; | ||
2454 | } | ||
2455 | #if ENABLE_FEATURE_VI_READONLY | ||
2456 | // got the file- read-only | ||
2457 | readonly = TRUE; | ||
2458 | #endif | ||
2459 | } | 2427 | } |
2460 | p = text_hole_make(p, size); | 2428 | p = text_hole_make(p, size); |
2461 | cnt = read(fd, p, size); | 2429 | cnt = read(fd, p, size); |
@@ -2475,6 +2443,19 @@ static int file_insert(char * fn, char * p, int size) | |||
2475 | return cnt; | 2443 | return cnt; |
2476 | } | 2444 | } |
2477 | 2445 | ||
2446 | #if ENABLE_FEATURE_VI_READONLY | ||
2447 | static void update_ro_status(const char *fn) | ||
2448 | { | ||
2449 | struct stat sb; | ||
2450 | if (stat(fn, &sb) == 0) { | ||
2451 | readonly = vi_readonly || (access(fn, W_OK) < 0) || | ||
2452 | /* root will always have access() | ||
2453 | * so we check fileperms too */ | ||
2454 | !(sb.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)); | ||
2455 | } | ||
2456 | } | ||
2457 | #endif | ||
2458 | |||
2478 | static int file_write(char * fn, char * first, char * last) | 2459 | static int file_write(char * fn, char * first, char * last) |
2479 | { | 2460 | { |
2480 | int fd, cnt, charcnt; | 2461 | int fd, cnt, charcnt; |