diff options
author | Paolo Bonzini <bonzini@gnu.org> | 2006-12-15 12:30:25 +0000 |
---|---|---|
committer | Paolo Bonzini <bonzini@gnu.org> | 2008-01-09 16:12:20 +0100 |
commit | ba68fb42b8db505a89da4987df5936997a3c226a (patch) | |
tree | 28c41aecc082a91b95312909851db53cb1bda464 | |
parent | 2128ec657b3d6bb3378424d0ddda923cdf8e2713 (diff) | |
download | sed-ba68fb42b8db505a89da4987df5936997a3c226a.tar.gz |
--posix disables all extensions to regular expressions
2006-12-15 Paolo Bonzini <bonzini@gnu.org>
* sed/regexp.c: Disable all extensions on --posix.
git-archimport-id: bonzini@gnu.org--2004b/sed--stable--4.1--patch-84
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | NEWS | 12 | ||||
-rw-r--r-- | configure.ac | 7 | ||||
-rw-r--r-- | doc/sed.1 | 4 | ||||
-rw-r--r-- | po/it.po | 91 | ||||
-rw-r--r-- | po/sed.pot | 81 | ||||
-rw-r--r-- | sed/execute.c | 13 | ||||
-rw-r--r-- | sed/regexp.c | 23 | ||||
-rw-r--r-- | sed/sed.c | 14 | ||||
-rw-r--r-- | sed/sed.h | 3 | ||||
-rw-r--r-- | sed/utils.c | 83 | ||||
-rw-r--r-- | sed/utils.h | 1 |
12 files changed, 259 insertions, 77 deletions
@@ -1,3 +1,7 @@ +2006-12-15 Paolo Bonzini <bonzini@gnu.org> + + * sed/regexp.c: Disable all extensions on --posix. + 2006-09-24 Paolo Bonzini <bonzini@gnu.org> * sed/execute.c: Support ACLs. @@ -1,3 +1,15 @@ +Sed 4.1b (release candidate for sed 4.2) + +* --posix disables all extensions to regular expressions. + +* new option --follow-symlinks, available when editing a file in-place. + This option may not be available on some systems (in this case, the + option will *not* be a no-op; it will be completely unavailable). + In the future, the option may be added as a no-op on systems without + symbolic links at all, since in this case a no-op is effectively + indistinguishable from a correct implementation. + +---------------------------------------------------------------------------- Sed 4.1a (release candidate for sed 4.2) * much improved portability diff --git a/configure.ac b/configure.ac index 53f2335..2fa56a0 100644 --- a/configure.ac +++ b/configure.ac @@ -85,6 +85,13 @@ enable_html=no) AM_CONDITIONAL(BUILD_HTML, test "x$enable_html" != xno) +# Check whether we are able to follow symlinks +AC_CHECK_FUNC(lstat, have_lstat=yes) +AC_CHECK_FUNC(readlink, have_readlink=yes) +if test "x$have_lstat" = xyes -a "x$have_readlink" = xyes; then + AC_DEFINE(ENABLE_FOLLOW_SYMLINKS, ,[Follow symlinks when processing in place]) +fi + : ${TEXI2HTML=texi2html -monolithic} AC_SUBST(TEXI2HTML) @@ -32,6 +32,10 @@ add the script to the commands to be executed .IP add the contents of script-file to the commands to be executed .HP +\fB\-\-follow\-symlinks\fR +.IP +follow symlinks when processing in place +.HP \fB\-i[SUFFIX]\fR, \fB\-\-in\-place\fR[=\fISUFFIX\fR] .IP edit files in place (makes backup if extension supplied) @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: sed 4.0a\n" "Report-Msgid-Bugs-To: bonzini@gnu.org\n" -"POT-Creation-Date: 2006-09-24 17:42+0200\n" +"POT-Creation-Date: 2006-11-28 17:57+0100\n" "PO-Revision-Date: 2002-11-26 12:44+0100\n" "Last-Translator: Paolo Bonzini <bonzini@gnu.org>\n" "Language-Team: Italian <tp@lists.linux.it>\n" @@ -175,27 +175,27 @@ msgid "couldn't edit %s: not a regular file" msgstr "impossibile modificare %s: non è un file normale" # lib/utils.c:131 -#: sed/execute.c:735 sed/utils.c:229 +#: sed/execute.c:735 sed/utils.c:233 #, c-format msgid "couldn't open temporary file %s: %s" msgstr "impossibile aprire il file temporaneo %s: %s" # sed/execute.c:1003 sed/execute.c:1183 -#: sed/execute.c:1258 sed/execute.c:1438 +#: sed/execute.c:1265 sed/execute.c:1445 msgid "error in subprocess" msgstr "errore in un sottoprocesso" # sed/execute.c:1005 -#: sed/execute.c:1260 +#: sed/execute.c:1267 msgid "option `e' not supported" msgstr "opzione `e' non supportata" # sed/execute.c:1185 -#: sed/execute.c:1440 +#: sed/execute.c:1447 msgid "`e' command not supported" msgstr "comando `e' non supportato" -#: sed/execute.c:1780 +#: sed/execute.c:1787 msgid "no input files" msgstr "nessun file in ingresso" @@ -216,7 +216,7 @@ msgid "invalid reference \\%d on `s' command's RHS" msgstr "riferimento non valido \\%d nel secondo membro del comando `s'" # sed/sed.c:98 -#: sed/sed.c:98 +#: sed/sed.c:101 msgid "" " -R, --regexp-perl\n" " use Perl 5's regular expressions syntax in the script.\n" @@ -224,7 +224,7 @@ msgstr "" " -R, --regexp-perl\n" " usa la sintassi Perl 5 per le espressioni regolari\n" -#: sed/sed.c:103 +#: sed/sed.c:106 #, c-format msgid "" "Usage: %s [OPTION]... {script-only-if-no-other-script} [input-file]...\n" @@ -234,7 +234,7 @@ msgstr "" "file]...\n" "\n" -#: sed/sed.c:107 +#: sed/sed.c:110 #, c-format msgid "" " -n, --quiet, --silent\n" @@ -243,7 +243,7 @@ msgstr "" " -n, --quiet, --silent\n" " sopprime la stampa automatica del pattern space\n" -#: sed/sed.c:109 +#: sed/sed.c:112 #, c-format msgid "" " -e script, --expression=script\n" @@ -252,7 +252,7 @@ msgstr "" " -e script, --expression=script\n" " aggiunge lo script ai comandi da eseguire\n" -#: sed/sed.c:111 +#: sed/sed.c:114 #, c-format msgid "" " -f script-file, --file=script-file\n" @@ -263,7 +263,16 @@ msgstr "" " aggiunge il contenuto di file-script ai comandi da " "eseguire\n" -#: sed/sed.c:113 +#: sed/sed.c:117 +#, c-format +msgid "" +" --follow-symlinks\n" +" follow symlinks when processing in place\n" +msgstr "" +" --follow-symlinks\n" +" segue i link simbolici quando viene utilizzato -i\n" + +#: sed/sed.c:120 #, c-format msgid "" " -i[SUFFIX], --in-place[=SUFFIX]\n" @@ -273,7 +282,7 @@ msgstr "" " scrive il risultato sul file originale (facendo una copia\n" " se è fornita un'estensione)\n" -#: sed/sed.c:116 +#: sed/sed.c:123 #, c-format msgid "" " -b, --binary\n" @@ -284,7 +293,7 @@ msgstr "" " apre i file in modo binario (lasciando le sequenze CR" "+LF se è immutate)\n" -#: sed/sed.c:119 +#: sed/sed.c:126 #, c-format msgid "" " -l N, --line-length=N\n" @@ -294,7 +303,7 @@ msgstr "" " specifica la lunghezza delle linee generate dal comando " "`l'\n" -#: sed/sed.c:121 +#: sed/sed.c:128 #, c-format msgid "" " --posix\n" @@ -304,7 +313,7 @@ msgstr "" " disabilita tutte le estensioni GNU.\n" # sed/sed.c:98 -#: sed/sed.c:123 +#: sed/sed.c:130 #, c-format msgid "" " -r, --regexp-extended\n" @@ -313,7 +322,7 @@ msgstr "" " -r, --regexp-extended\n" " usa la sintassi di `egrep' per le espressioni regolari\n" -#: sed/sed.c:126 +#: sed/sed.c:133 #, c-format msgid "" " -s, --separate\n" @@ -325,7 +334,7 @@ msgstr "" " considera i file di input come separati invece che come un\n" " unico file lungo.\n" -#: sed/sed.c:129 +#: sed/sed.c:136 #, c-format msgid "" " -u, --unbuffered\n" @@ -336,17 +345,17 @@ msgstr "" " -u, --unbuffered\n" " carica e visualizza i dati una a pezzetti piu' piccoli\n" -#: sed/sed.c:132 +#: sed/sed.c:139 #, c-format msgid " --help display this help and exit\n" msgstr " --help mostra questo aiuto ed esce\n" -#: sed/sed.c:133 +#: sed/sed.c:140 #, c-format msgid " --version output version information and exit\n" msgstr " --version stampa le informazioni sulla versione ed esce\n" -#: sed/sed.c:134 +#: sed/sed.c:141 #, c-format msgid "" "\n" @@ -366,7 +375,7 @@ msgstr "" "\n" # sed/sed.c:132 -#: sed/sed.c:140 +#: sed/sed.c:147 #, c-format msgid "" "E-mail bug reports to: %s .\n" @@ -376,13 +385,13 @@ msgstr "" "Assicurarsi di includere la parola ``%s'' nell'oggetto del messaggio.\n" # sed/sed.c:255 -#: sed/sed.c:285 +#: sed/sed.c:299 #, c-format msgid "super-sed version %s\n" msgstr "super-sed versione %s\n" # sed/sed.c:256 -#: sed/sed.c:286 +#: sed/sed.c:300 #, c-format msgid "" "based on GNU sed version %s\n" @@ -392,13 +401,13 @@ msgstr "" "\n" # sed/sed.c:258 -#: sed/sed.c:288 +#: sed/sed.c:302 #, c-format msgid "GNU sed version %s\n" msgstr "GNU sed versione %s\n" # sed/sed.c:260 -#: sed/sed.c:290 +#: sed/sed.c:304 #, c-format msgid "" "%s\n" @@ -413,39 +422,51 @@ msgstr "" "SCOPO, nei limiti permessi dalla legge.\n" # sed/execute.c:516 -#: sed/utils.c:98 sed/utils.c:363 +#: sed/utils.c:102 sed/utils.c:446 #, c-format msgid "cannot remove %s: %s" msgstr "impossibile rimuovere %s: %s" # lib/utils.c:131 -#: sed/utils.c:168 +#: sed/utils.c:172 #, c-format msgid "couldn't open file %s: %s" msgstr "impossibile aprire il file %s: %s" # lib/utils.c:161 -#: sed/utils.c:192 +#: sed/utils.c:196 #, c-format msgid "couldn't attach to %s: %s" -msgstr "Impossibile accedere a %s: %s" +msgstr "impossibile accedere a %s: %s" # lib/utils.c:161 -#: sed/utils.c:247 +#: sed/utils.c:251 #, c-format msgid "couldn't write %d item to %s: %s" msgid_plural "couldn't write %d items to %s: %s" -msgstr[0] "Impossibile scrivere %d elemento su %s: %s" -msgstr[1] "Impossibile scrivere %d elementi su %s: %s" +msgstr[0] "impossibile scrivere %d elemento su %s: %s" +msgstr[1] "impossibile scrivere %d elementi su %s: %s" # lib/utils.c:176 -#: sed/utils.c:262 sed/utils.c:278 +#: sed/utils.c:266 sed/utils.c:282 #, c-format msgid "read error on %s: %s" msgstr "errore di lettura su %s: %s" +# lib/utils.c:131 +#: sed/utils.c:386 +#, c-format +msgid "couldn't follow symlink %s: %s" +msgstr "impossibile seguire il link simbolico %s: %s" + +# sed/execute.c:516 +#: sed/utils.c:420 +#, c-format +msgid "cannot stat %s: %s" +msgstr "impossibile ottenere informazioni su %s: %s" + # sed/execute.c:516 -#: sed/utils.c:368 +#: sed/utils.c:451 #, c-format msgid "cannot rename %s: %s" msgstr "impossibile rinominare %s: %s" @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: bonzini@gnu.org\n" -"POT-Creation-Date: 2006-09-24 17:42+0200\n" +"POT-Creation-Date: 2006-11-28 17:57+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -148,24 +148,24 @@ msgstr "" msgid "couldn't edit %s: not a regular file" msgstr "" -#: sed/execute.c:735 sed/utils.c:229 +#: sed/execute.c:735 sed/utils.c:233 #, c-format msgid "couldn't open temporary file %s: %s" msgstr "" -#: sed/execute.c:1258 sed/execute.c:1438 +#: sed/execute.c:1265 sed/execute.c:1445 msgid "error in subprocess" msgstr "" -#: sed/execute.c:1260 +#: sed/execute.c:1267 msgid "option `e' not supported" msgstr "" -#: sed/execute.c:1440 +#: sed/execute.c:1447 msgid "`e' command not supported" msgstr "" -#: sed/execute.c:1780 +#: sed/execute.c:1787 msgid "no input files" msgstr "" @@ -182,34 +182,34 @@ msgstr "" msgid "invalid reference \\%d on `s' command's RHS" msgstr "" -#: sed/sed.c:98 +#: sed/sed.c:101 msgid "" " -R, --regexp-perl\n" " use Perl 5's regular expressions syntax in the script.\n" msgstr "" -#: sed/sed.c:103 +#: sed/sed.c:106 #, c-format msgid "" "Usage: %s [OPTION]... {script-only-if-no-other-script} [input-file]...\n" "\n" msgstr "" -#: sed/sed.c:107 +#: sed/sed.c:110 #, c-format msgid "" " -n, --quiet, --silent\n" " suppress automatic printing of pattern space\n" msgstr "" -#: sed/sed.c:109 +#: sed/sed.c:112 #, c-format msgid "" " -e script, --expression=script\n" " add the script to the commands to be executed\n" msgstr "" -#: sed/sed.c:111 +#: sed/sed.c:114 #, c-format msgid "" " -f script-file, --file=script-file\n" @@ -217,14 +217,21 @@ msgid "" "executed\n" msgstr "" -#: sed/sed.c:113 +#: sed/sed.c:117 +#, c-format +msgid "" +" --follow-symlinks\n" +" follow symlinks when processing in place\n" +msgstr "" + +#: sed/sed.c:120 #, c-format msgid "" " -i[SUFFIX], --in-place[=SUFFIX]\n" " edit files in place (makes backup if extension supplied)\n" msgstr "" -#: sed/sed.c:116 +#: sed/sed.c:123 #, c-format msgid "" " -b, --binary\n" @@ -232,28 +239,28 @@ msgid "" "specially)\n" msgstr "" -#: sed/sed.c:119 +#: sed/sed.c:126 #, c-format msgid "" " -l N, --line-length=N\n" " specify the desired line-wrap length for the `l' command\n" msgstr "" -#: sed/sed.c:121 +#: sed/sed.c:128 #, c-format msgid "" " --posix\n" " disable all GNU extensions.\n" msgstr "" -#: sed/sed.c:123 +#: sed/sed.c:130 #, c-format msgid "" " -r, --regexp-extended\n" " use extended regular expressions in the script.\n" msgstr "" -#: sed/sed.c:126 +#: sed/sed.c:133 #, c-format msgid "" " -s, --separate\n" @@ -262,7 +269,7 @@ msgid "" " long stream.\n" msgstr "" -#: sed/sed.c:129 +#: sed/sed.c:136 #, c-format msgid "" " -u, --unbuffered\n" @@ -271,17 +278,17 @@ msgid "" " the output buffers more often\n" msgstr "" -#: sed/sed.c:132 +#: sed/sed.c:139 #, c-format msgid " --help display this help and exit\n" msgstr "" -#: sed/sed.c:133 +#: sed/sed.c:140 #, c-format msgid " --version output version information and exit\n" msgstr "" -#: sed/sed.c:134 +#: sed/sed.c:141 #, c-format msgid "" "\n" @@ -292,31 +299,31 @@ msgid "" "\n" msgstr "" -#: sed/sed.c:140 +#: sed/sed.c:147 #, c-format msgid "" "E-mail bug reports to: %s .\n" "Be sure to include the word ``%s'' somewhere in the ``Subject:'' field.\n" msgstr "" -#: sed/sed.c:285 +#: sed/sed.c:299 #, c-format msgid "super-sed version %s\n" msgstr "" -#: sed/sed.c:286 +#: sed/sed.c:300 #, c-format msgid "" "based on GNU sed version %s\n" "\n" msgstr "" -#: sed/sed.c:288 +#: sed/sed.c:302 #, c-format msgid "GNU sed version %s\n" msgstr "" -#: sed/sed.c:290 +#: sed/sed.c:304 #, c-format msgid "" "%s\n" @@ -325,34 +332,44 @@ msgid "" "to the extent permitted by law.\n" msgstr "" -#: sed/utils.c:98 sed/utils.c:363 +#: sed/utils.c:102 sed/utils.c:446 #, c-format msgid "cannot remove %s: %s" msgstr "" -#: sed/utils.c:168 +#: sed/utils.c:172 #, c-format msgid "couldn't open file %s: %s" msgstr "" -#: sed/utils.c:192 +#: sed/utils.c:196 #, c-format msgid "couldn't attach to %s: %s" msgstr "" -#: sed/utils.c:247 +#: sed/utils.c:251 #, c-format msgid "couldn't write %d item to %s: %s" msgid_plural "couldn't write %d items to %s: %s" msgstr[0] "" msgstr[1] "" -#: sed/utils.c:262 sed/utils.c:278 +#: sed/utils.c:266 sed/utils.c:282 #, c-format msgid "read error on %s: %s" msgstr "" -#: sed/utils.c:368 +#: sed/utils.c:386 +#, c-format +msgid "couldn't follow symlink %s: %s" +msgstr "" + +#: sed/utils.c:420 +#, c-format +msgid "cannot stat %s: %s" +msgstr "" + +#: sed/utils.c:451 #, c-format msgid "cannot rename %s: %s" msgstr "" diff --git a/sed/execute.c b/sed/execute.c index 0ca2ca5..6b6632c 100644 --- a/sed/execute.c +++ b/sed/execute.c @@ -762,15 +762,22 @@ closedown(input) if (in_place_extension && output_file.fp != NULL) { + const char *target_name; ck_fclose (output_file.fp); + + if (follow_symlinks) + target_name = follow_symlink (input->in_file_name); + else + target_name = input->in_file_name; + if (strcmp(in_place_extension, "*") != 0) { - char *backup_file_name = get_backup_file_name(input->in_file_name); - ck_rename (input->in_file_name, backup_file_name, input->out_file_name); + char *backup_file_name = get_backup_file_name(target_name); + ck_rename (target_name, backup_file_name, input->out_file_name); free (backup_file_name); } - ck_rename (input->out_file_name, input->in_file_name, input->out_file_name); + ck_rename (input->out_file_name, target_name, input->out_file_name); free (input->out_file_name); } diff --git a/sed/regexp.c b/sed/regexp.c index 1297c5e..4daefe2 100644 --- a/sed/regexp.c +++ b/sed/regexp.c @@ -64,15 +64,24 @@ compile_regex_1 (new_regex, needed_sub) const char *error; int syntax = ((extended_regexp_flags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED - : RE_SYNTAX_POSIX_BASIC) - & ~RE_DOT_NOT_NULL; - - if (posixicity == POSIXLY_EXTENDED) - syntax &= ~RE_UNMATCHED_RIGHT_PAREN_ORD; - else - syntax |= RE_UNMATCHED_RIGHT_PAREN_ORD; + : RE_SYNTAX_POSIX_BASIC); + syntax &= ~RE_DOT_NOT_NULL; syntax |= RE_NO_POSIX_BACKTRACKING; + + switch (posixicity) + { + case POSIXLY_EXTENDED: + syntax &= ~RE_UNMATCHED_RIGHT_PAREN_ORD; + break; + case POSIXLY_CORRECT: + syntax |= RE_UNMATCHED_RIGHT_PAREN_ORD; + break; + case POSIXLY_BASIC: + syntax |= RE_UNMATCHED_RIGHT_PAREN_ORD | RE_LIMITED_OPS | RE_NO_GNU_OPS; + break; + } + #ifdef RE_ICASE syntax |= (new_regex->flags & REG_ICASE) ? RE_ICASE : 0; #endif @@ -72,6 +72,9 @@ bool no_default_output = false; /* If set, reset line counts on every new file. */ bool separate_files = false; +/* If set, follow symlinks when processing in place */ +bool follow_symlinks = false; + /* How do we edit files in-place? (we don't if NULL) */ char *in_place_extension = NULL; @@ -110,6 +113,10 @@ Usage: %s [OPTION]... {script-only-if-no-other-script} [input-file]...\n\ add the script to the commands to be executed\n")); fprintf(out, _(" -f script-file, --file=script-file\n\ add the contents of script-file to the commands to be executed\n")); +#ifdef ENABLE_FOLLOW_SYMLINKS + fprintf(out, _(" --follow-symlinks\n\ + follow symlinks when processing in place\n")); +#endif fprintf(out, _(" -i[SUFFIX], --in-place[=SUFFIX]\n\ edit files in place (makes backup if extension supplied)\n")); #if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(MSDOS) || defined(__EMX__) @@ -173,6 +180,9 @@ main(argc, argv) {"unbuffered", 0, NULL, 'u'}, {"version", 0, NULL, 'v'}, {"help", 0, NULL, 'h'}, +#ifdef ENABLE_FOLLOW_SYMLINKS + {"follow-symlinks", 0, NULL, 'F'}, +#endif {NULL, 0, NULL, 0} }; @@ -226,6 +236,10 @@ main(argc, argv) the_program = compile_file(the_program, optarg); break; + case 'F': + follow_symlinks = true; + break; + case 'i': separate_files = true; if (optarg == NULL) @@ -220,6 +220,9 @@ extern bool no_default_output; /* If set, reset line counts on every new file. */ extern bool separate_files; +/* If set, follow symlinks when invoked with -i option */ +extern bool follow_symlinks; + /* Do we need to be pedantically POSIX compliant? */ extern enum posixicity_types posixicity; diff --git a/sed/utils.c b/sed/utils.c index b4f0164..78bb2ff 100644 --- a/sed/utils.c +++ b/sed/utils.c @@ -35,6 +35,10 @@ # include <stdlib.h> #endif /* HAVE_STDLIB_H */ +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + #include "utils.h" const char *myname; @@ -342,6 +346,85 @@ do_ck_fclose(fp) } +/* Follow symlink and panic if something fails. Return the ultimate + symlink target, stored in a temporary buffer that the caller should + not free. */ +const char * +follow_symlink(const char *fname) +{ +#ifdef ENABLE_FOLLOW_SYMLINKS + static char *buf1, *buf2; + static int buf_size; + + struct stat statbuf; + const char *buf = fname, *c; + int rc; + + if (buf_size == 0) + { + buf1 = ck_malloc (PATH_MAX + 1); + buf2 = ck_malloc (PATH_MAX + 1); + buf_size = PATH_MAX + 1; + } + + while ((rc = lstat (buf, &statbuf)) == 0 + && (statbuf.st_mode & S_IFLNK) == S_IFLNK) + { + if (buf == buf2) + { + strcpy (buf1, buf2); + buf = buf1; + } + + while ((rc = readlink (buf, buf2, buf_size)) == buf_size) + { + buf_size *= 2; + buf1 = ck_realloc (buf1, buf_size); + buf2 = ck_realloc (buf2, buf_size); + } + if (rc < 0) + panic (_("couldn't follow symlink %s: %s"), buf, strerror(errno)); + else + buf2 [rc] = '\0'; + + if (buf2[0] != '/' && (c = strrchr (buf, '/')) != NULL) + { + /* Need to handle relative paths with care. Reallocate buf1 and + buf2 to be big enough. */ + int len = c - buf + 1; + if (len + rc + 1 > buf_size) + { + buf_size = len + rc + 1; + buf1 = ck_realloc (buf1, buf_size); + buf2 = ck_realloc (buf2, buf_size); + } + + /* Always store the new path in buf1. */ + if (buf != buf1) + memcpy (buf1, buf, len); + + /* Tack the relative symlink at the end of buf1. */ + memcpy (buf1 + len, buf2, rc + 1); + buf = buf1; + } + else + { + /* Use buf2 as the buffer, it saves a strcpy if it is not pointing to + another link. It works for absolute symlinks, and as long as + symlinks do not leave the current directory. */ + buf = buf2; + } + } + + if (rc < 0) + panic (_("cannot stat %s: %s"), buf, strerror(errno)); + + return buf; +#else + return fname; +#endif /* ENABLE_FOLLOW_SYMLINKS */ +} + /* Panic on failing rename */ void ck_rename (from, to, unlink_if_fail) diff --git a/sed/utils.h b/sed/utils.h index cef0f6d..a80202d 100644 --- a/sed/utils.h +++ b/sed/utils.h @@ -28,6 +28,7 @@ void ck_fwrite P_((const VOID *ptr, size_t size, size_t nmemb, FILE *stream)); size_t ck_fread P_((VOID *ptr, size_t size, size_t nmemb, FILE *stream)); void ck_fflush P_((FILE *stream)); void ck_fclose P_((FILE *stream)); +const char *follow_symlink P_((const char *path)); size_t ck_getline P_((char **text, size_t *buflen, FILE *stream)); FILE * ck_mkstemp P_((char **p_filename, char *tmpdir, char *base)); void ck_rename P_((const char *from, const char *to, const char *unlink_if_fail)); |