From 59a1f3045073c92c661035f87bdf7e28099358eb Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sat, 14 Jul 2007 22:43:10 +0000 Subject: [PATCH] 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 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 --- editors/vi.c | 99 +++++++++++++++++++++------------------------------- 1 file 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 static char readit(void); // read (maybe cursor) key from stdin static char get_one_char(void); // read 1 char from stdin static int file_size(const char *); // what is the byte size of "fn" -static int file_insert(char *, char *, int); +static int file_insert(char *, char *); +#if ENABLE_FEATURE_VI_READONLY +static void update_ro_status(const char *); +#else +static ALWAYS_INLINE void update_ro_status(const char *name) {} +#endif static int file_write(char *, char *, char *); static void place_cursor(int, int, int); static void screen_erase(void); @@ -419,8 +424,9 @@ static void edit_file(char * fn) new_text(size); // get a text[] buffer screenbegin = dot = end = text; if (fn != 0) { - ch = file_insert(fn, text, cnt); - } + ch = file_insert(fn, text); + update_ro_status(fn); + } if (ch < 1) { char_insert(text, '\n'); // start empty buf with dummy line } @@ -654,7 +660,6 @@ static void colon(char * buf) char *fn, cmd[MAX_LINELEN], args[MAX_LINELEN]; int i, l, li, ch, b, e; int useforce = FALSE, forced = FALSE; - struct stat st_buf; // :3154 // if (-e line 3154) goto it else stay put // :4,33w! foo // write a portion of buffer to file "foo" @@ -758,6 +763,7 @@ static void colon(char * buf) dot_skip_over_ws(); } else if (strncasecmp(cmd, "edit", i) == 0) { // Edit a file int sr; + struct stat st_buf; sr= 0; // don't edit, if the current file has been modified if (file_modified && ! useforce) { @@ -809,7 +815,8 @@ static void colon(char * buf) screenbegin = dot = end = text; // insert new file - ch = file_insert(fn, text, file_size(fn)); + ch = file_insert(fn, text); + update_ro_status(fn); if (ch < 1) { // start empty buf with dummy line @@ -937,25 +944,15 @@ static void colon(char * buf) // read after current line- unless user said ":0r foo" if (b != 0) q = next_line(q); -#if ENABLE_FEATURE_VI_READONLY - l = readonly; // remember current files' status -#endif - ch = file_insert(fn, q, file_size(fn)); -#if ENABLE_FEATURE_VI_READONLY - readonly = l; -#endif + ch = file_insert(fn, q); if (ch < 0) goto vc1; // nothing was inserted // how many lines in text[]? li = count_lines(q, q + ch - 1); psb("\"%s\"" -#if ENABLE_FEATURE_VI_READONLY - "%s" -#endif + USE_FEATURE_VI_READONLY("%s") " %dL, %dC", fn, -#if ENABLE_FEATURE_VI_READONLY - ((vi_readonly || readonly) ? " [Read only]" : ""), -#endif + USE_FEATURE_VI_READONLY(((vi_readonly || readonly) ? " [Read only]" : ""),) li, ch); if (ch > 0) { // 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 static int file_size(const char * fn) // what is the byte size of "fn" { struct stat st_buf; - int cnt, sr; + int cnt; - if (!fn || !fn[0]) - return -1; cnt = -1; - sr = stat(fn, &st_buf); // see if file exists - if (sr >= 0) { + if (fn && fn[0] && stat(fn, &st_buf) == 0) // see if file exists cnt = (int) st_buf.st_size; - } return cnt; } -static int file_insert(char * fn, char * p, int size) +static int file_insert(char * fn, char * p) { - int fd, cnt; - - cnt = -1; -#if ENABLE_FEATURE_VI_READONLY - readonly = FALSE; -#endif - if (!fn || !fn[0]) { - psbs("No filename given"); - goto fi0; - } - if (size == 0) { - // OK- this is just a no-op - cnt = 0; - goto fi0; - } + int cnt = -1; + int fd, size; + + size = file_size(fn); if (size < 0) { - psbs("Trying to insert a negative number (%d) of characters", size); + psbs("File does not exist"); goto fi0; } if (p < text || p > end) { @@ -2437,25 +2419,11 @@ static int file_insert(char * fn, char * p, int size) goto fi0; } - // see if we can open the file -#if ENABLE_FEATURE_VI_READONLY - if (vi_readonly) goto fi1; // do not try write-mode -#endif - fd = open(fn, O_RDWR); // assume read & write + // read file to buffer + fd = open(fn, O_RDONLY); if (fd < 0) { - // could not open for writing- maybe file is read only -#if ENABLE_FEATURE_VI_READONLY - fi1: -#endif - fd = open(fn, O_RDONLY); // try read-only - if (fd < 0) { - psbs("\"%s\" %s", fn, "cannot open file"); - goto fi0; - } -#if ENABLE_FEATURE_VI_READONLY - // got the file- read-only - readonly = TRUE; -#endif + psbs("\"%s\" %s", fn, "cannot open file"); + goto fi0; } p = text_hole_make(p, size); cnt = read(fd, p, size); @@ -2475,6 +2443,19 @@ static int file_insert(char * fn, char * p, int size) return cnt; } +#if ENABLE_FEATURE_VI_READONLY +static void update_ro_status(const char *fn) +{ + struct stat sb; + if (stat(fn, &sb) == 0) { + readonly = vi_readonly || (access(fn, W_OK) < 0) || + /* root will always have access() + * so we check fileperms too */ + !(sb.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)); + } +} +#endif + static int file_write(char * fn, char * first, char * last) { int fd, cnt, charcnt;