[Worth fixing. This patch needs more work though--scattering _WIN32 through the code like that is not how we want to separate out system-specific functionality. It would also be nice if there was a better way to figure out what names to reject--I may see if browsing the Microsoft documentation finds anything. But it may be that listing names as this patch does is the best choice. A post to info-cvs on 24 Jul 1998 lists the same file names as in this patch: CON PRN AUX LPTn (where n is 1-9) COMn (where n is 1-9) NUL -kingdon] From: Shankar Unni Subject: Patches for Win95 cvs problems To: bug-cvs@prep.ai.mit.edu Date: Fri, 21 Mar 1997 16:00:06 -0800 (PST) Attached is a patch (on CVS 1.9.2) for two problems I ran into using CVS on Windows 95 (as a client in a client-server environment). . . . 2. Checking out a file called, say "aux.h", or "con.c", onto a Windows client causes CVS to fail with bizarre errors, because Windows maps these names onto the underlying DOS devices AUX, CON, etc. (usually getting open failures, or permission failures). I put in a fix for this which tries to catch names of this sort, and just makes CVS put out a warning and skip that file. You can't actually create such a file under DOS, but you may have a repository on a Unix system with such a filename, in which case you are hosed anyway on Windows, and we might as well deal with it with as much grace as possible. The fix is, however, incomplete, as I don't know of a reliable way to generate a list of names that can map onto device names on a given system. I just have a list of popular names in windows-NT/filesubr.c. Both these are pretty easy to reproduce: . . . For "2.", create a repository file called "aux.h" and try to check it out. Here is the patch: [hand-edited to separate this out from the other patch which was submitted along with it -kingdon] Fri Mar 21 15:38:30 1997 Shankar Unni * src/client.c src/checkin.c src/update.c windows-NT/filesubr.c: fixes for Win32: catch any attempt to check in or out a file whose name happens to be a DOS magic name (AUX, CON, PRN, etc.). This includes files called, say, aux.h or con.c (DOS stupidity!). *** src/checkin.c.orig Tue Oct 29 12:50:45 1996 --- src/checkin.c Fri Mar 21 09:44:17 1997 *************** *** 19,24 **** --- 19,28 ---- #include "fileattr.h" #include "edit.h" + #ifdef _WIN32 + extern int is_magic_dos_file(const char *); + #endif /* _WIN32 */ + int Checkin (type, finfo, rcs, rev, tag, options, message) int type; *************** *** 33,38 **** --- 37,50 ---- Vers_TS *vers; int set_time; char *tocvsPath = NULL; + + #ifdef _WIN32 + /* Look for files called "aux.h", etc, that Win95 treats as magic names */ + if (is_magic_dos_file(finfo->file)) { + error(0,0, "checkin aborted for %s", finfo->file); + return(1); + } + #endif /* _WIN32 */ (void) printf ("Checking in %s;\n", finfo->fullname); fname = xmalloc (strlen (finfo->file) + 80); *** src/client.c.orig Wed Jan 15 13:16:46 1997 --- src/client.c Fri Mar 21 09:35:07 1997 *************** *** 1292,1297 **** --- 1292,1301 ---- char *timestamp; }; + #ifdef _WIN32 + extern int is_magic_dos_file(const char *); + #endif /* _WIN32 */ + /* Update the Entries line for this file. */ static void update_entries (data_arg, ent_list, short_pathname, filename) *************** *** 1315,1320 **** --- 1319,1336 ---- char *scratch_entries; int bin; + #ifdef _WIN32 + int noop = 0; + + /* Look for files called "aux.h", etc, that Win95 treats as magic names */ + if (is_magic_dos_file(filename)) { + error(0,0, "checkout aborted for %s", filename); + /* We cannot just return here - the server is going to follow up + * with a bunch of stuff that we have to accept and throw away */ + noop=1; + } + #endif /* _WIN32 */ + read_line (&entries_line); /* *************** *** 1443,1448 **** --- 1459,1472 ---- return; } + buf = xmalloc (size); + #ifdef _WIN32 + if (noop) { + /* Just skip over all this stuff and proceed to read the file */ + goto readloop; + } + #endif /* _WIN32 */ + temp_filename = xmalloc (strlen (filename) + 80); #ifdef USE_VMS_FILENAMES /* A VMS rename of "blah.dat" to "foo" to implies a *************** *** 1455,1461 **** sprintf (temp_filename, ".new.%s", filename); #endif /* _POSIX_NO_TRUNC */ #endif /* USE_VMS_FILENAMES */ - buf = xmalloc (size); /* Some systems, like OS/2 and Windows NT, end lines with CRLF instead of just LF. Format translation is done in the C --- 1479,1484 ---- *************** *** 1488,1501 **** --- 1511,1539 ---- if (use_gzip) fd = filter_through_gunzip (fd, 0, &gzip_pid); + #ifdef _WIN32 + readloop: + #endif /* _WIN32 */ if (size > 0) { read_from_server (buf, size); + #ifdef _WIN32 + if (!noop) + #endif /* _WIN32 */ if (write (fd, buf, size) != size) error (1, errno, "writing %s", short_pathname); } + #ifdef _WIN32 + if (noop) { + /* We are done with reading all that the server wants to send + * for this file, so we can just return at this point.. */ + free (mode_string); + free (buf); + return; + } + #endif /* _WIN32 */ if (close (fd) < 0) error (1, errno, "writing %s", short_pathname); if (gzip_pid > 0) *** src/update.c.orig Sat Nov 30 12:29:45 1996 --- src/update.c Fri Mar 21 09:37:44 1997 *************** *** 419,424 **** --- 419,427 ---- return (err); } + #ifdef _WIN32 + extern int is_magic_dos_file(const char *); + #endif /* _WIN32 */ /* * This is the callback proc for update. It is called for each file in each * directory by the recursion code. The current directory is the local *************** *** 441,446 **** --- 444,457 ---- int resurrecting; resurrecting = 0; + + #ifdef _WIN32 + /* Look for files called "aux.h", etc, that Win95 treats as magic names */ + if (is_magic_dos_file(finfo->file)) { + error(0,0, "checkout aborted for %s", finfo->file); + return(1); + } + #endif /* _WIN32 */ status = Classify_File (finfo, tag, date, options, force_tag_match, aflag, &vers, pipeout); *** windows-NT/filesubr.c.orig Wed Jan 8 20:04:24 1997 --- windows-NT/filesubr.c Fri Mar 21 09:31:04 1997 *************** *** 797,802 **** --- 797,834 ---- return path; } + /* + * Win95 treats certain filenames as magic (an old DOS hangover), ignoring + * the provided suffix. This happens for any file whose prefix matches one + * of the old builtin DOS filenames (CON, PRN, COM1, etc), so we have to + * catch them at the point of creation, and toss those files. This usually + * happens when checking out files from remote Unix or Windows-NT repositories. + */ + int is_magic_dos_file(char *path) + { + char locbuf[5]; + char *p = last_component(path); + char *q = locbuf; + while ((*q = FOLD_FN_CHAR(*p)) != 0 && *q != '.' && q <= locbuf+4) + q++, p++; + if (*q != 0 && *q != '.') + return 0; + if (*q == '.') + *q = 0; + if ((strcmp(locbuf, "con") == 0) || + (strcmp(locbuf, "prn") == 0) || + (strcmp(locbuf, "aux") == 0) || + (strcmp(locbuf, "nul") == 0) || + (strncmp(locbuf, "com", 3) == 0 && isdigit(locbuf[3]) && locbuf[4] == 0) || + (strncmp(locbuf, "lpt", 3) == 0 && isdigit(locbuf[3]) && locbuf[4] == 0)) { + /* uppercase the magic name for the error message */ + for (q = locbuf; *q; q++) + *q = toupper(*q); + error(0, 0, "file %s cannot be distinguished from the DOS magic file %s", path, locbuf); + return 1; + } + return 0; + } /* Read data from INFILE, and copy it to OUTFILE. Open INFILE using INFLAGS, and OUTFILE using OUTFLAGS. ============================== cut here ============================== -- Shankar Unni shankar@chromatic.com Chromatic Research (408) 752-9488