Index: src/client.c
===================================================================
RCS file: /home/cvs-adm/.cvsroot/cvs/src/client.c,v
retrieving revision 1.1.1.2
retrieving revision 1.3
diff -b -u -r1.1.1.2 -r1.3
--- src/client.c	2000/01/05 16:35:45	1.1.1.2
+++ src/client.c	2000/01/19 21:02:36	1.3
@@ -5775,6 +5775,20 @@
     send_to_server ("init ", 0);
     send_to_server (CVSroot_directory, 0);
     send_to_server ("\012", 0);
+}
+
+void
+to_server_buffer_flush (void)
+{
+    buf_flush (to_server, 1);
+}
+
+void
+from_server_buffer_read (line, lenp)
+     char **line;
+     int *lenp;
+{
+    buf_read_line (from_server, line, lenp);
 }
 
 #endif /* CLIENT_SUPPORT */
Index: src/client.h
===================================================================
RCS file: /home/cvs-adm/.cvsroot/cvs/src/client.h,v
retrieving revision 1.1.1.2
retrieving revision 1.3
diff -b -u -r1.1.1.2 -r1.3
--- src/client.h	2000/01/03 03:21:29	1.1.1.2
+++ src/client.h	2000/01/19 21:02:36	1.3
@@ -198,4 +198,7 @@
 	   int modtime));
 extern void client_import_done PROTO((void));
 extern void client_notify PROTO((char *, char *, char *, int, char *));
+
+extern void from_server_buffer_read PROTO((char **, int *));
+extern void to_server_buffer_flush PROTO((void));
 #endif /* CLIENT_SUPPORT */
Index: src/edit.c
===================================================================
RCS file: /home/cvs-adm/.cvsroot/cvs/src/edit.c,v
retrieving revision 1.1.1.2
retrieving revision 1.9
diff -b -u -r1.1.1.2 -r1.9
--- src/edit.c	1999/11/19 22:55:47	1.1.1.2
+++ src/edit.c	2000/01/31 17:33:11	1.9
@@ -16,6 +16,7 @@
 #include "edit.h"
 #include "fileattr.h"
 
+static int check_edited = 0;
 static int watch_onoff PROTO ((int, char **));
 
 static int setting_default;
@@ -269,6 +270,248 @@
     return err;
 }
 
+
+static int editors_output PROTO ((struct file_info *finfo));
+
+static int
+editors_output (finfo)
+    struct file_info *finfo;
+{
+    char *them;
+    char *p;
+
+    them = fileattr_get0 (finfo->file, "_editors");
+    if (them == NULL)
+	return 0;
+
+    cvs_output (finfo->fullname, 0);
+
+    p = them;
+    while (1)
+    {
+	cvs_output ("\t", 1);
+	while (*p != '>' && *p != '\0')
+	    cvs_output (p++, 1);
+	if (*p == '\0')
+	{
+	    /* Only happens if attribute is misformed.  */
+	    cvs_output ("\n", 1);
+	    break;
+	}
+	++p;
+	cvs_output ("\t", 1);
+	while (1)
+	{
+	    while (*p != '+' && *p != ',' && *p != '\0')
+		cvs_output (p++, 1);
+	    if (*p == '\0')
+	    {
+		cvs_output ("\n", 1);
+		goto out;
+	    }
+	    if (*p == ',')
+	    {
+		++p;
+		break;
+	    }
+	    ++p;
+	    cvs_output ("\t", 1);
+	}
+	cvs_output ("\n", 1);
+    }
+
+out:
+    free (them);
+
+    return 0;
+}
+
+
+static int check_fileproc PROTO ((void *callerdat, struct file_info *finfo));
+
+/* check file that is to be edited if it's already being edited */
+
+static int
+check_fileproc (callerdat, finfo)
+    void *callerdat;
+    struct file_info *finfo;
+{
+    char *editors = NULL;
+    int editors_found = 0;
+    int status;
+
+#ifdef CLIENT_SUPPORT
+    if (client_active)
+    {
+        int first_time;
+        int len = 0;
+        int possibly_more_editors = 0;
+
+        send_file_names (1, &finfo->fullname, SEND_EXPAND_WILD);
+        send_to_server ("editors\012", 0);
+
+        first_time = 1;
+        do
+        {
+            possibly_more_editors = 0;
+
+            to_server_buffer_flush ();
+            from_server_buffer_read (&editors, &len);
+
+            if (editors != NULL)
+            {
+                if (strcmp (editors, "ok") != 0)
+                {
+                    possibly_more_editors = 1;
+
+                    switch (editors[0])
+                    {
+                        case 'M':
+                        {
+                            editors_found = 1;
+
+                            if(!really_quiet)
+                            {
+                                cvs_output (editors + 2, 0);
+                                cvs_output ("\n", 0);
+                            }
+
+                            break;
+                        }
+
+                        default:
+                        {
+                            struct response *rs = NULL;
+                            char *cmd = NULL;
+
+                            cmd = editors;
+
+                            for (rs = responses; rs->name != NULL; ++rs)
+                                if (strncmp (cmd, rs->name, strlen (rs->name)) == 0)
+                                {
+                                    int cmdlen = strlen (rs->name);
+                                    if (cmd[cmdlen] == ' ')
+                                        ++cmdlen;
+                                    else if (cmd[cmdlen] != '\0')
+                                        /*
+                                         * The first len characters match, but it's a different
+                                         * response.  e.g. the response is "oklahoma" but we
+                                         * matched "ok".
+                                         */
+                                        continue;
+                                    (*rs->func) (cmd + cmdlen, len - cmdlen);
+                                    break;
+                                }
+                            if (rs->name == NULL)
+                                /* It's OK to print just to the first '\0'.  */
+                                /* We might want to handle control characters and the like
+                                   in some other way other than just sending them to stdout.
+                                   One common reason for this error is if people use :ext:
+                                   with a version of rsh which is doing CRLF translation or
+                                   something, and so the client gets "ok^M" instead of "ok".
+                                   Right now that will tend to print part of this error
+                                   message over the other part of it.  It seems like we could
+                                   do better (either in general, by quoting or omitting all
+                                   control characters, and/or specifically, by detecting the CRLF
+                                   case and printing a specific error message).  */
+                                error (0, 0,
+                                       "warning: unrecognized response `%s' from cvs server",
+                                       cmd);
+
+                            break;
+                        }
+                    }
+                }
+
+                free(editors);
+            }
+        } while (possibly_more_editors);
+    }
+    else
+#endif /* CLIENT_SUPPORT */
+    {
+        /* This is a somewhat screwy way to check for this, because it
+           doesn't help errors other than the nonexistence of the file
+           (e.g. permissions problems).  It might be better to rearrange
+           the code so that CVSADM_NOTIFY gets written only after the
+           various actions succeed (but what if only some of them
+           succeed).  */
+        if (!isfile (finfo->file))
+        {
+            error (0, 0, "no such file %s; ignored", finfo->fullname);
+            return 0;
+        }
+
+        editors = fileattr_get0 (finfo->file, "_editors");
+        if(!really_quiet && editors != NULL)
+        {
+            editors_output (finfo);
+        }
+
+        if(editors != NULL)
+        {
+            editors_found = 1;
+
+            free (editors);
+        }
+    }
+
+    if(check_edited && editors_found)
+    {
+        status = 1;
+    }
+    else
+    {
+        status = 0;
+    }
+
+    return status;
+}
+
+static int check_edits PROTO ((int, char **, int));
+
+/* Look through the CVS/fileattr file and check for editors */
+static int
+check_edits (argc, argv, local)
+    int argc;
+    char **argv;
+    int local;
+{
+    int err = 0;
+
+#ifdef CLIENT_SUPPORT
+    if (client_active)
+    {
+        if (strcmp (command_name, "release") != 0)
+        {
+            start_server ();
+            ign_setup ();
+        }
+
+        if (local)
+            send_arg ("-l");
+        send_files (argc, argv, local, 0, SEND_NO_CONTENTS);
+    }
+#endif
+
+	err += start_recursion (check_fileproc, (FILESDONEPROC) NULL,
+                            (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
+                            argc, argv, local, W_LOCAL, 0, 0, (char *)NULL,
+                            0);
+
+#ifdef CLIENT_SUPPORT
+    if (client_active)
+    {
+        send_to_server ("noop\012", 0);
+        if (strcmp (command_name, "release") == 0)
+            err += get_server_responses ();
+        else
+            err += get_responses_and_close ();
+    }
+#endif
+    return err;
+}
+
 static int edit_fileproc PROTO ((void *callerdat, struct file_info *finfo));
 
 static int
@@ -295,14 +538,28 @@
 	error (0, 0, "no such file %s; ignored", finfo->fullname);
 	return 0;
     }
-
     fp = open_file (CVSADM_NOTIFY, "a");
 
     (void) time (&now);
     ascnow = asctime (gmtime (&now));
     ascnow[24] = '\0';
-    fprintf (fp, "E%s\t%s GMT\t%s\t%s\t", finfo->file,
-	     ascnow, hostname, CurDir);
+
+    {
+        char *wd = (char *) malloc (strlen (CurDir) + strlen ("/") + strlen (finfo->update_dir) + 1);
+
+        strcpy(wd, CurDir);
+
+        if(finfo->update_dir != NULL  &&  *finfo->update_dir != '\0')
+        {
+            strcat(wd, "/");
+            strcat(wd, finfo->update_dir);
+        }
+
+        fprintf (fp, "E%s\t%s GMT\t%s\t%s\t", finfo->file, ascnow, hostname, wd);
+
+        free(wd);
+    }
+
     if (setting_tedit)
 	fprintf (fp, "E");
     if (setting_tunedit)
@@ -351,9 +608,11 @@
 
 static const char *const edit_usage[] =
 {
-    "Usage: %s %s [-lR] [files...]\n",
+    "Usage: %s %s [-cflR] [files...]\n",
+    "-c: Check that working files are unedited\n",
+    "-f: Force edit if working files are edited (default)\n",
     "-l: Local directory only, not recursive\n",
-    "-R: Process directories recursively\n",
+    "-R: Process directories recursively (default)\n",
     "-a: Specify what actions for temporary watch, one of\n",
     "    edit,unedit,commit,all,none\n",
     "(Specify the --help global option for a list of other help options)\n",
@@ -367,7 +626,7 @@
 {
     int local = 0;
     int c;
-    int err;
+    int err = 0;
     int a_omitted;
 
     if (argc == -1)
@@ -378,10 +637,16 @@
     setting_tunedit = 0;
     setting_tcommit = 0;
     optind = 0;
-    while ((c = getopt (argc, argv, "+lRa:")) != -1)
+    while ((c = getopt (argc, argv, "+cflRa:")) != -1)
     {
 	switch (c)
 	{
+            case 'c':
+                check_edited = 1;
+                break;
+            case 'f':
+                check_edited = 0;
+                break;
 	    case 'l':
 		local = 1;
 		break;
@@ -429,12 +694,19 @@
 
     /* No need to readlock since we aren't doing anything to the
        repository.  */
+    err = check_edits (argc, argv, local);
+    if(err)
+    {
+        error (1, 0, "files being edited!");
+    }
+    else
+    {
     err = start_recursion (edit_fileproc, (FILESDONEPROC) NULL,
 			   (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
 			   argc, argv, local, W_LOCAL, 0, 0, (char *)NULL,
 			   0);
-
     err += send_notifications (argc, argv, local);
+    }
 
     return err;
 }
@@ -624,7 +896,7 @@
 }
 
 
-void
+static void
 editor_set (filename, editor, val)
     char *filename;
     char *editor;
@@ -1026,50 +1298,7 @@
     void *callerdat;
     struct file_info *finfo;
 {
-    char *them;
-    char *p;
-
-    them = fileattr_get0 (finfo->file, "_editors");
-    if (them == NULL)
-	return 0;
-
-    cvs_output (finfo->fullname, 0);
-
-    p = them;
-    while (1)
-    {
-	cvs_output ("\t", 1);
-	while (*p != '>' && *p != '\0')
-	    cvs_output (p++, 1);
-	if (*p == '\0')
-	{
-	    /* Only happens if attribute is misformed.  */
-	    cvs_output ("\n", 1);
-	    break;
-	}
-	++p;
-	cvs_output ("\t", 1);
-	while (1)
-	{
-	    while (*p != '+' && *p != ',' && *p != '\0')
-		cvs_output (p++, 1);
-	    if (*p == '\0')
-	    {
-		cvs_output ("\n", 1);
-		goto out;
-	    }
-	    if (*p == ',')
-	    {
-		++p;
-		break;
-	    }
-	    ++p;
-	    cvs_output ("\t", 1);
-	}
-	cvs_output ("\n", 1);
-    }
-  out:;
-    return 0;
+    return editors_output (finfo);
 }
 
 int
Index: src/edit.h
===================================================================
RCS file: /home/cvs-adm/.cvsroot/cvs/src/edit.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -b -u -r1.1.1.1 -r1.2
--- src/edit.h	1999/12/27 13:46:33	1.1.1.1
+++ src/edit.h	2000/01/24 19:29:23	1.2
@@ -28,11 +28,6 @@
 extern void notify_do PROTO ((int type, char *filename, char *who,
 			      char *val, char *watches, char *repository));
 
-/* Set attributes to reflect the fact that EDITOR is editing FILENAME.
-   VAL is time+host+directory, or NULL if we are to say that EDITOR is
-   *not* editing FILENAME.  */
-extern void editor_set PROTO ((char *filename, char *editor, char *val));
-
 /* Take note of the fact that FILE is up to date (this munges CVS/Base;
    processing of CVS/Entries is done separately).  */
 extern void mark_up_to_date PROTO ((char *file));
Index: src/update.c
===================================================================
RCS file: /home/cvs-adm/.cvsroot/cvs/src/update.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -b -u -r1.1.1.2 -r1.2
--- src/update.c	2000/01/05 16:35:46	1.1.1.2
+++ src/update.c	2000/01/24 19:29:24	1.2
@@ -1374,22 +1374,6 @@
 		}
 	    }
 
-	    {
-		/* A newly checked out file is never under the spell
-		   of "cvs edit".  If we think we were editing it
-		   from a previous life, clean up.  Would be better to
-		   check for same the working directory instead of
-		   same user, but that is hairy.  */
-
-		struct addremove_args args;
-
-		editor_set (finfo->file, getcaller (), NULL);
-
-		memset (&args, 0, sizeof args);
-		args.remove_temp = 1;
-		watch_modify_watchers (finfo->file, &args);
-	    }
-
 	    /* set the time from the RCS file iff it was unknown before */
 	    set_time =
 		(!noexec
