Floppy handling Fix

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

 



I submitted this a while back, no comments were made but it was not
included either.

Changelog:

1	-	Fix incorrect reporting of no media in floppy drive as
		permissions problem.
2	-	Provide partial workaround for very long delays (c. 40 sec per
		lookup, about 7 minutes to set up file browser) on lookups to
		floppy drive not physically present (e.g. laptop with floppy or
		CD setup)

Index: wine/files/drive.c
===================================================================
RCS file: /home/wine/wine/files/drive.c,v
retrieving revision 1.74
diff -u -r1.74 drive.c
--- wine/files/drive.c	20 Jun 2002 23:21:27 -0000	1.74
+++ wine/files/drive.c	2 Jul 2002 18:19:38 -0000
@@ -7,6 +7,7 @@
  * Label & serial number read support.
  *  (c) 1999 Petr Tomasek <tomasek@etf.cuni.cz>
  *  (c) 2000 Andreas Mohr (changes)
+ *  (c) 2002 Keith Matthews (changes)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -36,6 +37,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <unistd.h>
+#include <time.h>
 
 #ifdef HAVE_SYS_PARAM_H
 # include <sys/param.h>
@@ -541,26 +543,126 @@
 #define DRIVE_SUPER 96
     int fd;
     off_t offs;
+    struct stat dev_data;
+    uid_t  user;
+    gid_t  group;
+    time_t call_start, call_end;
+    double time_diff;
     int ret = 0;
 
     if (memset(buff,0,DRIVE_SUPER)!=buff) return -1;
-    if ((fd=open(DOSDrives[drive].device,O_RDONLY)) == -1)
+
+    if ((DOSDrives[drive].flags & DRIVE_DISABLED))
+	return 0;		/*  should not get DEIVE_DISABLED here except as part
of
+				 *  non-existing floppy kludge
+				 */
+    if (!DOSDrives[drive].device)
     {
-	struct stat st;
-	if (!DOSDrives[drive].device)
-	    ERR("No device configured for drive %c: !\n", 'A'+drive);
-	else
-	    ERR("Couldn't open device '%s' for drive %c: ! (%s)\n",DOSDrives[drive].device, 'A'+drive,
-		 (stat(DOSDrives[drive].device, &st)) ?
-			"not available or symlink not valid ?" : "no permission");
-	ERR("Can't read drive volume info ! Either pre-set it or make sure the device to read it from is accessible !\n");
+	ERR("No Device Configured for drive %c: !\n",'A'+drive);
 	PROFILE_UsageWineIni();
 	return -1;
     }
 
+    if (( stat(DOSDrives[drive].device,&dev_data)) == -1)
+    {
+	if (errno == ENOENT || errno == ENOTDIR || errno == ELOOP || errno == ENAMETOOLONG )
+	{
+		        ERR("Device ('%s) Configured for drive %c:  is not a valid device path!\n",DOSDrives[drive].device,'A'+drive);
+		return -1;
+	} else if ( errno == EACCES )
+		ERR("Permissions problem on device for drive %c: !\n", 'A'+drive);
+        PROFILE_UsageWineIni();
+        return -1;
+    } else
+    {
+	user = getuid();
+	group = getgid();
+	if ( user == dev_data.st_uid)
+	{
+		/*  We are running as the device owner - check those perms    */
+		if ( (dev_data.st_mode & S_IRUSR) == 0 )
+		{
+			/* owner does not have read perms - stupid but  */
+			ERR("Permissions problem on device for drive %c: - user does not have read access !\n", 'A'+drive);
+        		PROFILE_UsageWineIni();
+        		return -1;
+		}
+	} else if ( group == dev_data.st_gid )
+	{
+		if ( (dev_data.st_mode & S_IRGRP) == 0 )
+		                {
+                        /* group  does not have read perms */
+                        ERR("Permissions problem on device for drive %c: - group does not have read access !\n", 'A'+drive);
+                        PROFILE_UsageWineIni();
+                        return -1;
+                }
+
+	} else if ( (dev_data.st_mode & S_IROTH) == 0 )
+	{
+                /* not owning user or group and no perms  */
+                ERR("Permissions problem on device for drive %c: - effective user does not have read access !\n", 'A'+drive);
+                PROFILE_UsageWineIni();
+                return -1;
+
+	}
+    }
+
+    time(&call_start);
+	
/*******************************************************************************
+		 *	start of kludge to trap situation where attempt is madeto address /dev/fd0
+		 * 	(or some such) and it is not actually present. Should never happen in
+		 *	desktop machine but could well happen on laptop.
+		 *
+		 *	Kludge only necessary as open thinks it can really open the file and
+		 *	takes 39 seconds to do it.
+		 *
+		
*******************************************************************************/
+
+    if ((fd=open(DOSDrives[drive].device,O_RDONLY)) == -1)
+    {
+	if (DOSDrives[drive].type == DRIVE_REMOVABLE )
+	{
+	
/*****************************************************************************
+		 *	OK, we've checked just about everything we can, it's a removeable media
+		 *	device, so assume no media since that gives same response
+		 *
+		 *	Wrong if not running as root and user does not have read to device but 
+		 *	we've already checked for that above
+		 *
+		
**************************************************************************/
+
+		DOSDrives[drive].flags = DOSDrives[drive].flags |DRIVE_NO_MEDIA;
+
+/* ++++++++++++++++	should we be down here for CD's also ?  also what about Jazz drives etc ?+++++++++++++++++++++++ */
+
+	} else {
+	
/****************************************************************************
+		 *
+		 *	Not removeable media device - must be permissions problem
+		 *
+		
***************************************************************************/
+            ERR("Couldn't open device '%s' for drive %c: ! (%s)\n", DOSDrives[drive].device, 'A'+drive,
+                        "no permission");
+        	ERR("Can't read drive volume info ! Either pre-set it or make sure the device to read it from is accessible !\n");
+        	PROFILE_UsageWineIni();
+        	return -1;
+
+	}
+    }
+
+    time(&call_end);
+    time_diff = difftime(call_end, call_start);
+    if (time_diff > 5 )
+    {
+	/* open took more that 5 sec. - error situation described above   */
+	DOSDrives[drive].flags = DOSDrives[drive].flags | DRIVE_DISABLED;
+	return 0; /* no point in erroring, act as if no media  */
+    }
+
     switch(DOSDrives[drive].type)
     {
 	case DRIVE_REMOVABLE:
+		/* leaves offs unset - is this critical ? */
 	case DRIVE_FIXED:
 	    offs = 0;
 	    break;
@@ -572,15 +674,17 @@
             break;
     }
 
-    if ((offs) && (lseek(fd,offs,SEEK_SET)!=offs))
-    {
-        ret = -4;
-        goto the_end;
-    }
-    if (read(fd,buff,DRIVE_SUPER)!=DRIVE_SUPER)
+    if ((offs) && (lseek(fd,offs,SEEK_SET)!=offs)) return -4;
+    if (read(fd,buff,DRIVE_SUPER)!=DRIVE_SUPER) 
     {
-        ret = -2;
-        goto the_end;
+	if (DOSDrives[drive].type != DRIVE_REMOVABLE)
+	{
+		return -2;
+	} else {
+		 DOSDrives[drive].flags = DOSDrives[drive].flags | DRIVE_NO_MEDIA;
+		return 0;
+    	}
+		
     }
 
     switch(DOSDrives[drive].type)


[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux