[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

MiNT 1.09: make Frename/Fdelete succeed on readonly files



This patch removes the silly restriction that readonly files cannot be
renamed or removed. Even on tosfs this will work now. The patch for
tosfs.c also fixes a bug where the FA_DELETE flag (delete on close) is
lost sometimes.

--- orig/dosdir.c	Mon Aug  2 18:57:34 1993
+++ dosdir.c	Sat Nov 13 17:34:54 1993
@@ -741,6 +741,7 @@
 		DEBUG(("Fdelete(%s): write access to directory denied",name));
 	} else {
 /* BUG: we should check here for a read-only file */
+/* No: this should depend on the file system */
 		r = (*dir.fs->remove)(&dir,temp1);
 	}
 	release_cookie(&dir);
@@ -752,8 +753,11 @@
 	int junk;		/* ignored, for TOS compatibility */
 	const char *old, *new;
 {
-	fcookie olddir, newdir, oldfil;
+	fcookie olddir, newdir;
+#if 0
+	fcookie oldfil;
 	XATTR xattr;
+#endif
 	char temp1[PATH_MAX], temp2[PATH_MAX];
 	long r;
 
@@ -766,6 +770,9 @@
 		DEBUG(("Frename(%s,%s): error parsing old name",old,new));
 		return r;
 	}
+
+#if 0 /* this should depend on the file system */
+
 /* check for permissions on the old file
  * GEMDOS doesn't allow rename if the file is FA_RDONLY
  * we enforce this restriction only on regular files; processes,
@@ -786,6 +793,8 @@
 		release_cookie(&olddir);
 		return EACCDN;
 	}
+#endif
+
 	r = path2cookie(new, temp1, &newdir);
 	if (r) {
 		DEBUG(("Frename(%s,%s): error parsing new name",old,new));
@@ -800,6 +809,13 @@
 		return EXDEV;	/* cross device rename */
 	}
 
+	if (newdir.dev != olddir.dev) {
+		DEBUG(("Frename(%s,%s): different devices",old,new));
+		release_cookie(&olddir);
+		release_cookie(&newdir);
+		return EXDEV;	/* cross device rename */
+	}
+
 /* check for write permission on both directories */
 	r = dir_access(&olddir, S_IWOTH);
 	if (!r) r = dir_access(&newdir, S_IWOTH);
@@ -1042,6 +1058,13 @@
 		return EXDEV;	/* cross device link */
 	}
 
+	if (newdir.dev != olddir.dev) {
+		DEBUG(("Flink(%s,%s): different devices",old,new));
+		release_cookie(&olddir);
+		release_cookie(&newdir);
+		return EXDEV;	/* cross device link */
+	}
+
 /* check for write permission on the destination directory */
 
 	r = dir_access(&newdir, S_IWOTH);
--- orig/tosfs.c	Fri Jun 25 22:24:32 1993
+++ tosfs.c	Sat Nov 13 19:26:02 1993
@@ -507,7 +507,7 @@
 		ti->size = foo.dta_size;
 		ti->date = foo.dta_date;
 		ti->time = foo.dta_time;
-		ti->attr = foo.dta_attrib;
+		ti->attr = foo.dta_attrib | (ti->attr & FA_DELETE);
 		if (executable_extension(foo.dta_name))
 			ti->attr |= FA_EXEC;
 		ti->valid = 1;
@@ -560,7 +560,7 @@
 		ti->size = foo.dta_size;
 		ti->date = foo.dta_date;
 		ti->time = foo.dta_time;
-		ti->attr = foo.dta_attrib;
+		ti->attr = foo.dta_attrib | (ti->attr & FA_DELETE);
 		if (executable_extension(foo.dta_name))
 			ti->attr |= FA_EXEC;
 around:
@@ -672,19 +672,37 @@
 	const char *name;
 {
 	struct tindex *ti;
+	long r;
+	int attr;
 
 	(void)tfullpath(tmpbuf, (struct tindex *)dir->index, name);
 
 	ti = tstrindex(tmpbuf);
 	if (ti->open) {
 		DEBUG(("tos_remove: file is open, will be deleted later"));
-		if (ti->attr & FA_RDONLY)
-			return EACCDN;
 		ti->attr |= FA_DELETE;
 		return 0;
 	}
-	ti->valid = 0;
-	return Fdelete(tmpbuf);
+	r = Fdelete (tmpbuf);
+	if (r == EACCDN)
+	  {
+	    if (ti->valid)
+	      attr = ti->attr;
+	    else
+	      {
+		attr = Fattrib (tmpbuf, 0, 0);
+		if (attr < 0)
+		  attr = 0;
+	      }
+	    if (attr & FA_RDONLY)
+	      {
+		(void) Fattrib (tmpbuf, 1, attr & ~FA_RDONLY);
+		r = Fdelete (tmpbuf);
+		if (r < 0)
+		  (void) Fattrib (tmpbuf, 1, attr);
+	      }
+	  }
+	return r;
 }
 
 static long ARGS_ON_STACK 
@@ -730,6 +748,19 @@
 	(void)tfullpath(tmpbuf, (struct tindex *)olddir->index, oldname);
 	(void)tfullpath(newbuf, (struct tindex *)newdir->index, newname);
 	r = Frename(0, tmpbuf, newbuf);
+	if (r == EACCDN)
+	  {
+	    int attr = Fattrib (tmpbuf, 0, 0);
+	    if (attr >= 0 && attr & FA_RDONLY)
+	      {
+		(void) Fattrib (tmpbuf, 1, attr & ~FA_RDONLY);
+		r = Frename (0, tmpbuf, newbuf);
+		if (r == 0)
+		  (void) Fattrib (newbuf, 1, attr);
+		else
+		  (void) Fattrib (tmpbuf, 1, attr);
+	      }
+	  }
 	if (r == 0) {
 		ti = tstrindex(tmpbuf);
 		kfree(ti->name);
@@ -1310,11 +1341,20 @@
 		r = Fclose((int)f->devinfo);
 
 /* if the file was marked for deletion, delete it */
-		if (!t->open) {
-			if (t->attr & FA_DELETE) {
-				(void)Fdelete(t->name);
-				t->name = 0;
-			}
+		if (!t->open && t->attr & FA_DELETE) {
+			int attr;
+			if (t->valid)
+			  attr = t->attr;
+			else
+			  {
+			    attr = Fattrib (t->name, 0, 0);
+			    if (attr < 0)
+			      attr = 0;
+			  }
+			if (attr & FA_RDONLY)
+			  (void) Fattrib (t->name, 1, attr & ~FA_RDONLY);
+			(void)Fdelete(t->name);
+			t->name = 0;
 		}
 	}
 	return r;