sed/sed-follow_symlinks.patch

225 lines
6.6 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Index: sed-4.1.5/sed/sed.c
===================================================================
--- sed-4.1.5.orig/sed/sed.c
+++ sed-4.1.5/sed/sed.c
@@ -70,6 +70,11 @@ bool no_default_output = false;
/* If set, reset line counts on every new file. */
bool separate_files = false;
+#ifdef ENABLE_FOLLOW_SYMLINKS
+/* If set, follow symlinks when processing in place */
+bool follow_symlinks = false;
+#endif
+
/* How do we edit files in-place? (we don't if NULL) */
char *in_place_extension = NULL;
@@ -105,6 +110,10 @@ Usage: %s [OPTION]... {script-only-if-no
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"));
fprintf(out, _(" -l N, --line-length=N\n\
@@ -163,6 +172,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}
};
@@ -215,6 +227,12 @@ main(argc, argv)
the_program = compile_file(the_program, optarg);
break;
+#ifdef ENABLE_FOLLOW_SYMLINKS
+ case 'F':
+ follow_symlinks = true;
+ break;
+#endif
+
case 'i':
separate_files = true;
if (optarg == NULL)
Index: sed-4.1.5/lib/utils.c
===================================================================
--- sed-4.1.5.orig/lib/utils.c
+++ sed-4.1.5/lib/utils.c
@@ -35,6 +35,13 @@
# include <stdlib.h>
#endif /* HAVE_STDLIB_H */
+#ifdef ENABLE_FOLLOW_SYMLINKS
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <unistd.h>
+# include <libgen.h>
+#endif /* ENABLE_FOLLOW_SYMLINKS */
+
#include "utils.h"
const char *myname;
@@ -315,6 +322,65 @@ do_ck_fclose(fp)
}
+#ifdef ENABLE_FOLLOW_SYMLINKS
+static char buf[2048], buf2[2048];
+static size_t bufsize = sizeof (buf);
+
+/* Follow symlink and panic if something fails. Returned value is
+ ultimate symlink target, stored in temporary buffer. You need to
+ strdup the return value, if you intend to use it later.*/
+const char *
+ck_follow_symlink(const char * fname)
+{
+ static struct stat statbuf;
+ int err;
+ char * dir;
+
+ if (strlen (fname) >= bufsize)
+ panic("ck_follow_symlink: file name too long");
+ strcpy (buf, fname);
+
+ while (1)
+ {
+ err = lstat (buf, &statbuf);
+
+ if (err != 0)
+ panic("ck_follow_symlink: couldn't lstat %s: %s", buf, strerror(errno));
+
+ if ((statbuf.st_mode & S_IFLNK) == S_IFLNK)
+ {
+ err = readlink (buf, buf2, bufsize);
+
+ if (err < 0)
+ panic("ck_follow_symlink: readlink failed on %s: %s", buf, strerror(errno));
+ else if (err == bufsize)
+ panic("ck_follow_symlink: pointee name too long");
+ else
+ buf2 [err] = '\0';
+
+ /* need to handle relative paths with care */
+ if (buf2[0] != '/')
+ {
+ dir = dirname (buf); // dir part of orig path
+ int len = strlen (dir); // orig path len
+ buf[len] = '/';
+ strncpy (buf+len+1, buf2, bufsize - len - 1);
+ if (buf[bufsize-1] != 0)
+ panic("ck_follow_symlink: pointee name too long");
+ }
+ else
+ {
+ strcpy (buf, buf2);
+ }
+ }
+ else
+ break;
+ }
+
+ return buf;
+}
+#endif /* ENABLE_FOLLOW_SYMLINKS */
+
/* Panic on failing rename */
void
ck_rename (from, to, unlink_if_fail)
Index: sed-4.1.5/lib/utils.h
===================================================================
--- sed-4.1.5.orig/lib/utils.h
+++ sed-4.1.5/lib/utils.h
@@ -27,6 +27,9 @@ void ck_fwrite P_((const VOID *ptr, size
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));
+#ifdef ENABLE_FOLLOW_SYMLINKS
+const char *ck_follow_symlink P_((const char *path));
+#endif
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));
Index: sed-4.1.5/sed/execute.c
===================================================================
--- sed-4.1.5.orig/sed/execute.c
+++ sed-4.1.5/sed/execute.c
@@ -711,16 +711,34 @@ closedown(input)
if (in_place_extension && output_file.fp != NULL)
{
+#ifdef ENABLE_FOLLOW_SYMLINKS
+ char *target_name;
+
+ if (follow_symlinks)
+ target_name = ck_strdup(ck_follow_symlink(input->in_file_name));
+ else
+ target_name = ck_strdup(input->in_file_name);
+#else
+ const char *target_name;
+
+ target_name = input->in_file_name;
+#endif
+
ck_fclose (output_file.fp);
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);
+#ifdef ENABLE_FOLLOW_SYMLINKS
+ free (target_name);
+#endif
}
input->fp = NULL;
Index: sed-4.1.5/sed/sed.h
===================================================================
--- sed-4.1.5.orig/sed/sed.h
+++ sed-4.1.5/sed/sed.h
@@ -219,6 +219,11 @@ extern bool no_default_output;
/* If set, reset line counts on every new file. */
extern bool separate_files;
+#ifdef ENABLE_FOLLOW_SYMLINKS
+/* If set, follow symlinks when invoked with -i option */
+extern bool follow_symlinks;
+#endif
+
/* Do we need to be pedantically POSIX compliant? */
extern enum posixicity_types posixicity;
Index: sed-4.1.5/configure.ac
===================================================================
--- sed-4.1.5.orig/configure.ac
+++ sed-4.1.5/configure.ac
@@ -117,6 +117,13 @@ enable_html=no)
AM_CONDITIONAL(BUILD_HTML, test "x$enable_html" != xno)
+# 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)