--- fileio.c.~1~	Thu May  1 08:50:25 1997
+++ fileio.c	Mon Jul 27 17:49:58 1998
@@ -291,6 +291,52 @@
   DoCommand(args);
 }
 
+/*
+ * Attempt to determine if we're opening the named file or if it
+ * has been replaced by a symbolic link to someplace not nice.
+ * Algorithm is:
+ *
+ *	1) lstat( name );
+ *		if a symbolic link don't even try the open
+ *	2) fd = open( name );
+ *	3) fstat( fd );
+ *	4) lstat( name );
+ *	5) if fstat st_dev and st_ino don't match the lstat values
+ *		then we lost a race and someone added a link between
+ *		the first lstat and the open.  Close the file and
+ *		log an error.  Note: this can still cause problems;
+ *		e.g. a link to /dev/st0 will cause a tape to be
+ *		rewound when the file is closed.
+ */
+static FILE *
+NoLinkOpen( char * fn, char * mode )
+{
+  struct stat linkstat;
+  struct stat filestat;
+  FILE * f;
+
+  if ( lstat( fn, &linkstat ) == 0 &&
+       linkstat.st_mode == S_IFLNK )
+    goto err;
+
+  f = fopen( fn, mode );
+  if ( ! f )
+    return 0;
+
+  if ( fstat( fileno( f ), &filestat ) == 0 &&
+       lstat( fn, &linkstat ) == 0 &&
+       linkstat.st_mode != S_IFLNK &&
+       linkstat.st_dev == filestat.st_dev &&
+       linkstat.st_ino == filestat.st_ino )
+    return f;
+
+  fclose( f );
+
+ err:
+  Msg(0, "Warning: file not opened, \"%s\" is a symbolic link.", fn);
+  return 0;
+}
+
 void
 WriteFile(dump)
 int dump;
@@ -337,7 +383,7 @@
   if (UserContext() > 0)
     {
       debug("Writefile: usercontext\n");
-      if ((f = fopen(fn, mode)) == NULL)
+      if ((f = NoLinkOpen(fn, mode)) == NULL)
 	{
 	  debug2("WriteFile: fopen(%s,\"%s\") failed\n", fn, mode);
 	  UserReturn(0);
