[6515] in Athena Bugs

home help back first fref pref prev next nref lref last post

rt 7.1H: dosread

daemon@ATHENA.MIT.EDU (daemon@ATHENA.MIT.EDU)
Mon Dec 3 00:34:49 1990

From: drmorris@ATHENA.MIT.EDU
To: bugs@ATHENA.MIT.EDU
Date: Mon, 03 Dec 90 00:34:27 EST

System name:		cookie-dough
Type and version:	RTPC-ROMPC 7.1H (1 update(s) to same version)
Display type:		apa16

What were you trying to do?
	Read a file in a subdirectory with the total pathname longer
than 8 characters.

What's wrong:
	dosread truncates the filename after 8 characters.  As such, a
filename like "elisp/msort.el" will get truncated to "elisp/ms.el".
E.g.:

[/usr/tmp]:cookie-dough % dosdir -R
elisp
elisp/msort.el
elisp/ms.el
[/usr/tmp]:cookie-dough % dosread -R elisp/msort.el
[/usr/tmp]:cookie-dough % ls elisp/
ms.el

What should have happened:
	dosread should truncate each element of the path at 8 charaters
for a filename followed by a 3 character extension.

Please describe any relevant documentation references:

*** /source/bsd-4.3/common/ibm/dosread.c	Sat Mar  3 12:59:16 1990
--- ./dosread.c	Mon Dec  3 00:23:25 1990
***************
*** 116,123 ****
  int		oflg;		/* use old dosdir output format */
  int             isize;		/* size (in blocks) of diskette (or disk) */
  int		first_sector;	/* sector number to start allocation at */
- char            s1[] = {'d', 'w'};
- char            s2[] = {'.'};
  
  char           *dostime();
  char           *dosdate();
--- 116,121 ----
***************
*** 1265,1309 ****
  
  catname(fn)
      char            fn[];
  {
!     int             i;
!     if (any(s2, fn))
      {
! 	for (i = 0; i < 8 && fn[i] != '.'; i++);
! 	if (i == 8 && fn[8] == '.')
! 	    fn[12] = '\0';
! 	else
  	{
! 	    if (i == 8)
  	    {
! 		fn[8] = '.';
! 		for (i = 9; fn[i] != '.'; i++);
! 		fn[9] = fn[i + 1];
! 		fn[10] = fn[i + 2];
! 		fn[11] = fn[i + 3];
! 		fn[12] = '\0';
! 	    } else
! 		fn[i + 4] = '\0';
! 	}
!     } else
!     {
! 	for (i = 0; i < 8; i++)
! 	    if (fn[i] == '\0')
  		break;
! 	fn[i] = '\0';
      }
  }
  
- any(plist, s)
-     register char  *plist, *s;
- {
-     register char  *t;
-     for (; *s; s++)
- 	for (t = plist; *t; t++)
- 	    if (*s == *t)
- 		return (*s);
-     return (0);
- }
  char           *
  strsave(s)
      register char  *s;
--- 1263,1400 ----
  
  catname(fn)
      char            fn[];
+ /*
+  * Convert a unix filename into a DOS acceptable version.
+  *
+  * DOS requires an 8 character filename followed by an optional
+  * extension of '.' + 3 characters.  Coversion is as follows:
+  *
+  * All path components are truncated to 8 characters up to a '.', and
+  * 3 characters after.
+  * e.g.
+  * "longfilename.test" -> "longfile.tes"
+  * "longdirectory.name/filename" -> "longdire.nam/filename"
+  */
  {
!     /* Create a simple FSM, which scans over the filename, truncating
!      * the filename and extension as necessary.
!      */
! #define SLASH	1
! #define FILENAME	2
! #define FILENAME_TRUNC	3
! #define EXTENSION	4
! #define EXTENSION_TRUNC	5
! 
!     char	    state = SLASH, count = 0;
!     char	    *curr;
! 
!     curr = fn;
! 
!     while (*fn)
      {
! 	switch (state)
  	{
! 	case SLASH:
! 	    switch (*fn)
  	    {
! 	    case '/':
! 		/* don't want leading slashes, and want multiple
! 		 * slashes to be combined to a single slash, so
! 		 * swallow it.
! 		 */
! 		fn++;
  		break;
! 	    case '.':
! 		/* User is confused, filenames should not start with
! 		 * '.' under DOS.
! 		 */
! 		state = FILENAME;
! 		*curr++ = *fn++;
! 		break;
! 	    default:
! 		state = FILENAME;
! 		*curr++ = *fn++;
! 		count++;
! 		break;
! 	    }
! 	    break;
! 	case FILENAME:
! 	    switch (*fn)
! 	    {
! 	    case '/':
! 		state = SLASH;
! 		count = 0;
! 		*curr++ = *fn++;
! 		break;
! 	    case '.':
! 		state = EXTENSION;
! 		count = 0;
! 		*curr++ = *fn++;
! 		break;
! 	    default:
! 		*curr++ = *fn++;
! 		count++;
! 		if (count >= 8) state = FILENAME_TRUNC;
! 		break;
! 	    }
! 	    break;
! 	case FILENAME_TRUNC:
! 	    switch (*fn)
! 	    {
! 	    case '/':
! 		state = SLASH;
! 		count = 0;
! 		*curr++ = *fn++;
! 		break;
! 	    case '.':
! 		state = EXTENSION;
! 		count = 0;
! 		*curr++ = *fn++;
! 		break;
! 	    default:
! 		fn++;
! 		break;
! 	    }
! 	    break;
! 	case EXTENSION:
! 	    switch (*fn)
! 	    {
! 	    case '/':
! 		state = SLASH;
! 		count = 0;
! 		*curr++ = *fn++;
! 		break;
! 	    case '.':
! 		/* User is confused, can't have a '.' in an extension */
! 		state = EXTENSION_TRUNC;
! 		count = 0;
! 		fn++;
! 		break;
! 	    default:
! 		*curr++ = *fn++;
! 		count++;
! 		if (count >= 3) state = EXTENSION_TRUNC;
! 		break;
! 	    }
! 	    break;
! 	case EXTENSION_TRUNC:
! 	    switch (*fn)
! 	    {
! 	    case '/':
! 		state = SLASH;
! 		count = 0;
! 		*curr++ = *fn++;
! 		break;
! 	    default:
! 		fn++;
! 		break;
! 	    }
! 	    break;
! 	}
      }
+     *curr = '\0';
  }
  
  char           *
  strsave(s)
      register char  *s;


home help back first fref pref prev next nref lref last post