? enh-multiple_edits.diff
? vms/Makefile
Index: lib/ChangeLog
===================================================================
RCS file: /home/nyap/.cvsroot/cvs/lib/ChangeLog,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -r1.1.1.1 -r1.1.1.1.4.1
0a1,9
> 2001-03-06  Noel Yap <yap_noel@yahoo.com>
> 
> 	* stripslash.c (strip_trailing_slashes)
> 	Changed to use ISDIRSEP().
> 
> 	* system.h (ISDIRSEP)
> 	Changed on NT to check for '\\' as well.
> 	DIRSEP added to be the typical directory separator string.
> 
11c20
< 	
---
> 
Index: lib/stripslash.c
===================================================================
RCS file: /home/nyap/.cvsroot/cvs/lib/stripslash.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -r1.1.1.1 -r1.1.1.1.4.1
17a18,19
> #include "system.h"
> 
38c40
<   while (last > 0 && path[last] == '/')
---
>   while (last > 0 && ISDIRSEP (path[last]))
Index: lib/system.h
===================================================================
RCS file: /home/nyap/.cvsroot/cvs/lib/system.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -r1.1.1.1 -r1.1.1.1.4.1
206c206
< **     remaining systems that neither statement is true, _POSIX_PATH_MAX 
---
> **     remaining systems that neither statement is true, _POSIX_PATH_MAX
245c245
< #ifndef PATH_MAX  
---
> #ifndef PATH_MAX
483c483
< #define ISDIRSEP(c) (FOLD_FN_CHAR(c) == '/')
---
> #define ISDIRSEP(c) (FOLD_FN_CHAR(c) == '/'  ||  FOLD_FN_CHAR(c) == '\\')
490c490
< /* Fold characters in FILENAME to their canonical forms.  
---
> /* Fold characters in FILENAME to their canonical forms.
511a512,519
> #endif
> 
> #ifndef DIRSEP
> #if defined (WIN32)
> #define DIRSEP "\\"
> #else
> #define DIRSEP "/"
> #endif /* defined (WIN32) */
Index: src/ChangeLog
===================================================================
RCS file: /home/nyap/.cvsroot/cvs/src/ChangeLog,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.2
diff -r1.1.1.1 -r1.1.1.1.4.2
1c1,30
< 2000-09-19  Larry Jones  <larry.jones@sdrc.com> 
---
> 2001-03-06  Noel Yap <yap_noel@yahoo.com>
> 
> 	* version.c: Version 1.11 (multiple edits)
> 
> 	* commit.c (find_fileproc, commit, commit_fileproc, update_delproc):
> 	File information sent to server and used to unedit file.
> 
> 	* cvs.h:
> 	repository, hostname, wd, and editor added to logfile_info
> 
> 	* edit.c (ncheck_fileproc, notify_put, unedit_fileproc, notify_proc,
> 	notify_do):
> 	Editor key changed to include file location.
> 
> 	* edit.c (notify_put)
> 	Relative paths removed from working directories.
> 
> 	* edit.h (notify_do):
> 	editor argument added.
> 
> 	* rcs.c (RCS_unlock):
> 	Notification removed.
> 
> 	* server.c, server.h (serve_fileinfo, server_getfileinfo,
> 	server_delfileinfolist, serve_notify, server_notify):
> 	FileInfo added to allow client to tell server about file
> 	information (eg file location, editor).  This information
> 	is used by commit to know which editor to unedit.
> 
> 2000-09-19  Larry Jones  <larry.jones@sdrc.com>
Index: src/add.c
===================================================================
RCS file: /home/nyap/.cvsroot/cvs/src/add.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -r1.1.1.1 -r1.1.1.1.4.1
4c4
<  * 
---
>  *
7c7
<  * 
---
>  *
9c9
<  * 
---
>  *
15c15
<  * 
---
>  *
19c19
<  * 
---
>  *
22c22
<  * 
---
>  *
661c661
<  * 
---
>  *
792a793,796
>         li->repository = NULL;
>         li->hostname = NULL;
>         li->wd = NULL;
>         li->editor = NULL;
Index: src/commit.c
===================================================================
RCS file: /home/nyap/.cvsroot/cvs/src/commit.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.2
diff -r1.1.1.1 -r1.1.1.1.4.2
296a297,301
>     data->repository = xstrdup (finfo->repository);
>     data->hostname = xstrdup (hostname);
>     data->wd = (char *) xmalloc (strlen (CurDir) + sizeof ('/') + strlen (finfo->update_dir) + 1);
>     sprintf (data->wd, "%s%c%s", CurDir, finfo->update_dir != NULL  &&  *finfo->update_dir != '\0'   ?   '/'   :   '\0', finfo->update_dir);
>     data->editor = NULL;
548a554,577
>         /* send local file info to server */
>         if (supported_request ("FileInfo"))
>         {
>             char **v = NULL;
> 
>             for(v = find_args.argv; v < find_args.argv + find_args.argc; ++v)
>             {
>                 Node *p = NULL;
> 
>                 p = findnode (find_args.ulist, *v);
>                 if (p != NULL)
>                 {
>                     send_to_server ("FileInfo ", 0);
>                     send_to_server (*v, 0);
>                     send_to_server ("\012", 1);
>                     send_to_server (((struct logfile_info *) p->data)->hostname, 0);
>                     send_to_server ("\t", 1);
>                     send_to_server (((struct logfile_info *) p->data)->wd, 0);
>                     send_to_server ("\t", 1);
>                     send_to_server ("\012", 1);
>                 }
>             }
>         }
> 
579a609,640
>         if (err == 0  &&  !supported_request ("FileInfo"))
>         {
>             /* FIXME: Noel Yap (yap_noel@yahoo.com) 2000 Feb 28
>                This block is to support old servers.  It should be
>                removed once it's deemed that all servers support the
>                "FileInfo" request.  IMHO, it should be safe to remove
>                by 2002 Feb 28 (ie in two years).
>             */
>             char **v = NULL;
> 
>             for(v = find_args.argv; v < find_args.argv + find_args.argc; ++v)
>             {
>                 Node *p = NULL;
> 
>                 p = findnode (find_args.ulist, *v);
>                 if (p != NULL)
>                 {
>                     char *repository = NULL;
>                     char *user = NULL;
> 
>                     user = getcaller ();
>                     repository = ((struct logfile_info *) p->data)->repository;
> 
>                     fileattr_startdir (repository);
> 
>                     notify_do ('C', *v, user, user, NULL, "", repository);
> 
>                     fileattr_free ();
>                 }
>             }
>         }
> 
649a711,717
> #ifdef SERVER_SUPPORT
>     if (server_active)
>     {
>       server_delfileinfolist ();
>     }
> #endif
> 
824a893
>         {
997a1067,1163
> 
> #if SERVER_SUPPORT
>             if (server_active)
>             {
>                 struct logfile_info *client_fileinfo = NULL;
> 
>                 client_fileinfo = server_getfileinfo (finfo->fullname);
>                 if (client_fileinfo == NULL)
>                 {
>                     li->repository = NULL;
>                     li->hostname = NULL;
>                     li->wd = NULL;
>                 }
>                 else
>                 {
>                     li->repository = xstrdup (client_fileinfo->repository);
>                     li->hostname = xstrdup (client_fileinfo->hostname);
>                     li->wd = xstrdup (client_fileinfo->wd);
>                 }
>             }
>             else
> #endif
>             {
>                 li->repository = xstrdup (finfo->repository);
>                 li->hostname = xstrdup (hostname);
>                 li->wd = (char *) xmalloc (strlen (CurDir) + sizeof ('/') + strlen (finfo->update_dir) + 1);
> 
>                 strcpy (li->wd, CurDir);
>                 if (finfo->update_dir != NULL  &&  *finfo->update_dir != '\0')
>                 {
>                     strcat (li->wd, "/");
>                     strcat (li->wd, finfo->update_dir);
>                 }
>             }
> 
>             if (li->hostname == NULL  ||  li->wd == NULL)
>             {
>                 li->editor = NULL;
>             }
>             else
>             {
>                 char *editors = NULL;
> 
>                 editors = fileattr_get0 (finfo->file, "_editors");
>                 if (editors == NULL)
>                 {
>                     li->editor = NULL;
>                 }
>                 else
>                 {
>                     char *editor = NULL;
>                     char *user = NULL;
>                     char *p = NULL;
>                     char *p0 = NULL;
> 
>                     user = getcaller ();
> 
>                     editor = (char *) xmalloc (strlen (user) + sizeof ('@') + strlen (li->hostname) + sizeof (':') + strlen (li->wd) + 1);
>                     sprintf (editor, "%s@%s:%s", user, li->hostname, li->wd);
> 
>                     p = editors;
>                     p0 = p;
>                     while (*p != '\0')
>                     {
>                         p = strchr (p, '>');
>                         if (p == NULL)
>                         {
>                             break;
>                         }
>                         *p = '\0';
>                         if (strcmp (editor, p0) == 0)
>                         {
>                             break;
>                         }
>                         p = strchr (p, ',');
>                         if (p == NULL)
>                         {
>                             break;
>                         }
>                         ++p;
>                         p0 = p;
>                     }
> 
>                     if (strcmp (editor, p0) == 0)
>                     {
>                         li->editor = editor;
>                     }
>                     else
>                     {
>                         li->editor = NULL;
>                         free (editor);
>                     }
> 
>                     free (editors);
>                 }
>             }
> 
1057a1224,1225
>         }
> 
1360c1528,1566
<     notify_do ('C', finfo->file, getcaller (), NULL, NULL, finfo->repository);
---
>     {
>         char *editor = NULL;
> 
> #ifdef SERVER_SUPPORT
>         if (server_active)
>         {
>             Node *p = NULL;
> 
>             p = findnode (ulist, finfo->file);
>             if (p != NULL)
>             {
>                 struct logfile_info *li = NULL;
> 
>                 li = (struct logfile_info *) p->data;
>                 if (li != NULL)
>                 {
>                     editor = li->editor;
>                 }
>             }
> 
>             notify_do ('C', finfo->file, getcaller (), editor ? editor : getcaller (), NULL, "", finfo->repository);
>         }
>         else
> #endif
>         {
>             editor = (char *) xmalloc (strlen (getcaller ()) + sizeof ('@') + strlen (hostname) + sizeof (':') + strlen (CurDir) + sizeof ('/') + strlen (finfo->update_dir) + 1);
>             sprintf (editor, "%s@%s:%s", getcaller (), hostname, CurDir);
> 
>             if (*finfo->update_dir != '\0')
>             {
>                 strcat (editor, "/");
>                 strcat (editor, finfo->update_dir);
>             }
> 
>             notify_do ('C', finfo->file, getcaller (), editor, NULL, "", finfo->repository);
> 
>             free (editor);
>         }
>     }
2304a2511,2518
>     if (li->repository)
>         free (li->repository);
>     if (li->hostname)
>         free (li->hostname);
>     if (li->wd)
>         free (li->wd);
>     if (li->editor)
>         free (li->editor);
Index: src/cvs.h
===================================================================
RCS file: /home/nyap/.cvsroot/cvs/src/cvs.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -r1.1.1.1 -r1.1.1.1.4.1
160c160
<    
---
> 
558c558
< extern void expand_wild PROTO ((int argc, char **argv, 
---
> extern void expand_wild PROTO ((int argc, char **argv,
795a796,799
>   char *repository;
>   char *hostname;
>   char *wd;     /* working directory */
>   char *editor;
Index: src/edit.c
===================================================================
RCS file: /home/nyap/.cvsroot/cvs/src/edit.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.2
diff -r1.1.1.1 -r1.1.1.1.4.2
18a19,20
> #include <assert.h>
> 
156a159
>     char *editor = NULL;
201c204
< 	cp = strchr (cp, '\n');
---
> 	cp = strchr (cp, '\t');
203a207,211
> 	*cp++ = '\0';
>         editor = cp;
>         cp = strchr (cp, '\t');
>         if (cp == NULL)
> 	    continue;
206c214
< 	notify_do (notif_type, filename, getcaller (), val, watches,
---
> 	notify_do (notif_type, filename, getcaller (), editor, val, watches,
272c280
< static int edit_fileproc PROTO ((void *callerdat, struct file_info *finfo));
---
> static void notify_put PROTO ((struct file_info *finfo, char *editor, char action, int tedit, int tunedit, int tcommit));
274,276c282,283
< static int
< edit_fileproc (callerdat, finfo)
<     void *callerdat;
---
> static void
> notify_put (finfo, editor, action, tedit, tunedit, tcommit)
277a285,289
>     char *editor;
>     char action;
>     int tedit;
>     int tunedit;
>     int tcommit;
282,297c294
<     char *basefilename;
< 
<     if (noexec)
< 	return 0;
< 
<     /* 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;
<     }
---
>     char *wd = NULL;
304,306c301,383
<     fprintf (fp, "E%s\t%s GMT\t%s\t%s\t", finfo->file,
< 	     ascnow, hostname, CurDir);
<     if (setting_tedit)
---
> 
>     wd = (char *) malloc (strlen (CurDir) + strlen (DIRSEP) + strlen (finfo->update_dir) + 1);
>     strcpy(wd, CurDir);
>     if (finfo->update_dir != NULL && *finfo->update_dir != '\0')
>     {
>         strcat (wd, DIRSEP);
>         strcat (wd, finfo->update_dir);
>     }
> 
>     /* remove "./" */
>     {
>         char *p = NULL;
> 
>         assert (strlen (wd) > 1
>                 && (wd[0] != '.'  ||  !ISDIRSEP(wd[1])));
> 
>         for (p = strstr (wd, ".");
>              p < wd + strlen (wd)  &&  p != NULL;
>              p = strstr (p + 1, "."))
>         {
>             if (ISDIRSEP (*(p - 1))
>                 && ISDIRSEP (*(p + 1)))
>             {
>                 char *p0 = NULL;
>                 char *p1 = NULL;
> 
>                 for (p0 = p, p1 = p + 2;
>                      p1 < wd + strlen (wd)  &&  *p1 != '\0';
>                      ++p0, ++p1)
>                 {
>                     *p0 = *p1;
>                 }
> 
>                 *p0 = '\0';
>             }
>         }
>     }
> 
>     /* remove "../" */
>     {
>         char *p = NULL;
> 
>         assert (strlen (wd) > 2
>                 && (wd[0] != '.'  ||  wd[1] != '.'  ||  !ISDIRSEP(wd[2])));
> 
>         for (p = strstr (wd, "..");
>              p < wd + strlen (wd)  &&  p != NULL;
>              p = strstr (p + 2, ".."))
>         {
>             if (ISDIRSEP (*(p - 1))
>                 && ISDIRSEP (*(p + 2)))
>             {
>                 char *p0 = NULL;
>                 char *p1 = NULL;
> 
>                 p0 = p - 1;
>                 do
>                 {
>                     --p0;
>                 }
>                 while (p0 >wd  &&  !ISDIRSEP (*p0));
> 
>                 p1 = p + 2;
>                 do
>                 {
>                     ++p1;
>                 }
>                 while (p1 < wd + strlen (wd)  &&  !ISDIRSEP (*p1));
> 
>                 for (; p1 < wd + strlen (wd)  &&  *p1 != '\0'; ++p0, ++p1)
>                 {
>                     *p0 = *p1;
>                 }
> 
>                 *p0 = '\0';
>             }
>         }
>     }
> 
>     strip_trailing_slashes (wd);
> 
>     fprintf (fp, "%c%s\t%s GMT\t%s\t%s\t", action, finfo->file, ascnow, hostname, wd);
>     if (tedit)
308c385
<     if (setting_tunedit)
---
>     if (tunedit)
310c387
<     if (setting_tcommit)
---
>     if (tcommit)
311a389,398
> 
>     if (editor == NULL  ||  strcmp (editor, "") == 0)
>     {
>         fprintf (fp, "\t%s@%s:%s\t", getcaller (), hostname, wd);
>     }
>     else
>     {
>         fprintf (fp, "\t%s\t", editor);
>     }
> 
322a410,439
>     if (wd != NULL)
>         free (wd);
> }
> 
> static int edit_fileproc PROTO ((void *callerdat, struct file_info *finfo));
> 
> static int
> edit_fileproc (callerdat, finfo)
>     void *callerdat;
>     struct file_info *finfo;
> {
>     char *basefilename;
> 
>     if (noexec)
> 	return 0;
> 
>     /* 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;
>     }
> 
>     notify_put (finfo, NULL, 'E', setting_tedit, setting_tunedit, setting_tcommit);
> 
375d491
< 
491,506c607
<     fp = open_file (CVSADM_NOTIFY, "a");
< 
<     (void) time (&now);
<     ascnow = asctime (gmtime (&now));
<     ascnow[24] = '\0';
<     fprintf (fp, "U%s\t%s GMT\t%s\t%s\t\n", finfo->file,
< 	     ascnow, hostname, CurDir);
< 
<     if (fclose (fp) < 0)
<     {
< 	if (finfo->update_dir[0] == '\0')
< 	    error (0, errno, "cannot close %s", CVSADM_NOTIFY);
< 	else
< 	    error (0, errno, "cannot close %s/%s", finfo->update_dir,
< 		   CVSADM_NOTIFY);
<     }
---
>     notify_put (finfo, NULL, 'U', 0, 0, 0);
558a660,661
> 
>         xchmod (finfo->file, 0);
561d663
<     xchmod (finfo->file, 0);
665c767
<     char *notifyee;
---
>     char *watcher;
690c792
<     prog = xmalloc (strlen (filter) + strlen (args->notifyee) + 1);
---
>     prog = xmalloc (strlen (filter) + strlen (args->watcher) + 1);
692c794
<        the notifyee.  We only allocated enough memory for one %s, and I doubt
---
>        the watcher.  We only allocated enough memory for one %s, and I doubt
700c802
< 		strcpy (q, args->notifyee);
---
> 		strcpy (q, args->watcher);
747c849
< notify_do (type, filename, who, val, watches, repository)
---
> notify_do (type, filename, who, editor, val, watches, repository)
750a853
>     char *editor;
756a860
>     int edit_count = 0;
772c876
< 	    editor_set (filename, who, val);
---
> 	    editor_set (filename, editor, val);
776c880
< 	    editor_set (filename, who, NULL);
---
> 	    editor_set (filename, editor, NULL);
798,800c902,932
< 	    /* Don't notify user of their own changes.  Would perhaps
< 	       be better to check whether it is the same working
< 	       directory, not the same user, but that is hairy.  */
---
>             char *e = NULL;
>             char *editors = NULL;
> 
>             editors = fileattr_get0 (filename, "_editors");
>             e = editors;
>             while (e != NULL)
> 	{
>                 char *e_at = NULL;
>                 char *e_end = NULL;
>                 char *e_gt = NULL;
> 
>                 e_at = strchr (e, '@');
>                 e_gt = strchr (e, '>');
> 
>                 e_end = (e_at != NULL)   ?   e_at   :   e_gt;
> 
>                 if ((size_t) (e_end - e) == strlen (who)  &&
>                     strncmp (who, e, e_end - e) == 0)
>                 {
>                     ++edit_count;
>                 }
> 
>                 e = strchr (e, ',');
>                 if (e != NULL)
>                 {
>                     ++e;
>                 }
>             }
> 
>             if (edit_count <= 1)
>             {
804a937,942
>             if (editors != NULL)
>             {
>                 free (editors);
>             }
> 	}
> 
871c1009
< 	    args.notifyee = NULL;
---
> 	    args.watcher = NULL;
892c1030
< 			args.notifyee = xstrdup (line + len + 1);
---
> 			args.watcher = xstrdup (line + len + 1);
899c1037
< 			cp = strpbrk (args.notifyee, ":\n");
---
> 			cp = strpbrk (args.watcher, ":\n");
915c1053
< 	    if (args.notifyee == NULL)
---
> 	    if (args.watcher == NULL)
917,919c1055,1057
< 		args.notifyee = xmalloc (endp - p + 1);
< 		strncpy (args.notifyee, p, endp - p);
< 		args.notifyee[endp - p] = '\0';
---
> 		args.watcher = xmalloc (endp - p + 1);
> 		strncpy (args.watcher, p, endp - p);
> 		args.watcher[endp - p] = '\0';
928c1066
< 	    free (args.notifyee);
---
> 	    free (args.watcher);
935a1074,1075
>     if (edit_count <= 1)
>     {
959a1100
>     }
Index: src/edit.h
===================================================================
RCS file: /home/nyap/.cvsroot/cvs/src/edit.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -r1.1.1.1 -r1.1.1.1.4.1
28a29
>                               char *editor,
Index: src/import.c
===================================================================
RCS file: /home/nyap/.cvsroot/cvs/src/import.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -r1.1.1.1 -r1.1.1.1.4.1
4c4
<  * 
---
>  *
7c7
<  * 
---
>  *
10c10
<  * 
---
>  *
376a377,380
>     li->repository = NULL;
>     li->hostname = NULL;
>     li->wd = NULL;
>     li->editor = NULL;
643c647
< 	 * 
---
> 	 *
1276c1280
< 	    
---
> 
1528c1532
<  * 
---
>  *
Index: src/rcs.c
===================================================================
RCS file: /home/nyap/.cvsroot/cvs/src/rcs.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -r1.1.1.1 -r1.1.1.1.4.1
3c3
<  * 
---
>  *
6c6
<  * 
---
>  *
200c200
<     if ((fp = CVS_FOPEN (rcsfile, FOPEN_BINARY_READ)) != NULL) 
---
>     if ((fp = CVS_FOPEN (rcsfile, FOPEN_BINARY_READ)) != NULL)
203c203
< 	if (rcs != NULL) 
---
> 	if (rcs != NULL)
217c217
<     if ((fp = CVS_FOPEN (rcsfile, FOPEN_BINARY_READ)) != NULL) 
---
>     if ((fp = CVS_FOPEN (rcsfile, FOPEN_BINARY_READ)) != NULL)
251c251
< 	    if (rcs != NULL) 
---
> 	    if (rcs != NULL)
326c326
<  */ 
---
>  */
1538c1538
<    
---
> 
2069c2069
<  * 
---
>  *
2072c2072
<  * 
---
>  *
2154c2154
< 	/* Nope, none such. If tag is not a branch we're done. */ 
---
> 	/* Nope, none such. If tag is not a branch we're done. */
2176c2176
<        /* Tag is branch, but does not exist, try corresponding 
---
>        /* Tag is branch, but does not exist, try corresponding
2179c2179
< 	* FIXME: assumes all magic branches are of       
---
> 	* FIXME: assumes all magic branches are of
2183c2183
< 	*/ 
---
> 	*/
2218c2218
<  * 
---
>  *
2220c2220
<  * 
---
>  *
2240c2240
<     if (rcs->flags & PARTIAL) 
---
>     if (rcs->flags & PARTIAL)
2437c2437
<  * Given an RCSNode, returns non-zero if the specified revision number 
---
>  * Given an RCSNode, returns non-zero if the specified revision number
2440c2440
<  * FIXME: this is the same as RCS_nodeisbranch except for the special 
---
>  * FIXME: this is the same as RCS_nodeisbranch except for the special
2762c2762
<     {	
---
>     {
3260,3262c3260,3262
<  * TRUE if argument has valid syntax for an RCS revision or 
<  * branch number.  All characters must be digits or dots, first 
<  * and last characters must be digits, and no two consecutive 
---
>  * TRUE if argument has valid syntax for an RCS revision or
>  * branch number.  All characters must be digits or dots, first
>  * and last characters must be digits, and no two consecutive
3265c3265
<  * Intended for classifying things, so this function doesn't 
---
>  * Intended for classifying things, so this function doesn't
3268c3268
< int 
---
> int
4791c4791
<    
---
> 
4918c4918
< 	    
---
> 
5327c5327
< 	get_file (changefile, changefile, 
---
> 	get_file (changefile, changefile,
5370c5370
< 	
---
> 
5487c5487
< 	
---
> 
5491c5491
< 	
---
> 
5503c5503
< 	
---
> 
5508c5508
< 	
---
> 
5763c5763
< 	/* Break the lock. */	    
---
> 	/* Break the lock. */
5795,5796c5795,5796
<    lock and notify them.  It is an open issue whether RCS_unlock
<    queries the user about whether or not to break the lock. */
---
>    lock.  It is an open issue whether RCS_unlock queries the user
>    about whether or not to break the lock. */
5874,5887d5873
<     if (! STREQ (lock->data, user))
<     {
<         /* If the revision is locked by someone else, notify
< 	   them.  Note that this shouldn't ever happen if RCS_unlock
< 	   is called with a NULL revision, since that means "whatever
< 	   revision is currently locked by the caller." */
< 	char *repos, *workfile;
< 	repos = xstrdup (rcs->path);
< 	workfile = strrchr (repos, '/');
< 	*workfile++ = '\0';
< 	notify_do ('C', workfile, user, NULL, NULL, repos);
< 	free (repos);
<     }
< 
6521c6507
< int 
---
> int
6537c6523
<  * This includes magic branch revisions, not found in rcs->versions, 
---
>  * This includes magic branch revisions, not found in rcs->versions,
6539c6525
<  * Take advantage of list walk callback function already used by 
---
>  * Take advantage of list walk callback function already used by
7378c7364
<     /* Make sure that it is a revision number and not a cabbage 
---
>     /* Make sure that it is a revision number and not a cabbage
7869c7855
<                "error parsing repository file %s, file may be corrupt.", 
---
>                "error parsing repository file %s, file may be corrupt.",
7872c7858
<  
---
> 
7997c7983
< 	   
---
> 
Index: src/server.c
===================================================================
RCS file: /home/nyap/.cvsroot/cvs/src/server.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.2
diff -r1.1.1.1 -r1.1.1.1.4.2
387c387
<     
---
> 
450,451c450,451
< 	    
< 	    
---
> 
> 
752c752
<     
---
> 
930c930
< 	
---
> 
1019c1019
<     
---
> 
1915a1916,2039
> List *fileinfo_list = NULL;
> 
> static void serve_fileinfo PROTO ((char *));
> 
> static void
> serve_fileinfo (arg)
>      char *arg;
> {
>     char *data = NULL;
>     int status;
> 
>     status = buf_read_line (buf_from_net, &data, (int *) NULL);
>     if (status != 0)
>     {
> 	if (status == -2)
>         {
> 	    pending_error = ENOMEM;
>         }
> 	else
> 	{
> 	    pending_error_text = malloc (80 + strlen (arg));
> 	    if (pending_error_text == NULL)
>             {
> 		pending_error = ENOMEM;
>             }
> 	    else
> 	    {
> 		if (status == -1)
>                 {
> 		    sprintf (
>                         pending_error_text,
>                         "E end of file reading notification for %s",
>                         arg);
>                 }
> 		else
> 		{
> 		    sprintf (
>                         pending_error_text,
>                         "E error reading notification for %s",
>                         arg);
> 		    pending_error = status;
> 		}
> 	    }
> 	}
>     }
>     else
>     {
>         char *cp = NULL;
>         char *cp0 = NULL;
>         struct logfile_info *li;
>         Node *p = NULL;
> 
>         if (fileinfo_list == NULL)
>         {
>             fileinfo_list = getlist ();
>         }
> 
>         p = getnode ();
>         p->key = xstrdup (arg);
>         p->type = UPDATE;
>         p->delproc = update_delproc;
> 
>         li = (struct logfile_info *) xmalloc (sizeof (struct logfile_info));
>         li->type = T_UNKNOWN;
>         li->repository = NULL;
> 
>         cp = data;
> 
>         cp0 = cp;
>         cp = strchr (cp0, '\t');
>         if (cp == NULL)
>         {
>             goto error;
>         }
>         *cp++ = '\0';
> 
>         li->hostname = xstrdup (cp0);
> 
>         cp0 = cp;
>         cp = strchr (cp0, '\t');
>         if (cp != NULL)
>         {
>             *cp = '\0';
>         }
> 
>         li->wd = xstrdup (cp0);
>         li->editor = NULL;
> 
>         li->tag = NULL;
>         li->rev_old = NULL;
>         li->rev_new = NULL;
> 
>         p->data = (char *) li;
>         (void) addnode (fileinfo_list, p);
>     }
> 
> error:
>     return;
> }
> 
> struct logfile_info *
> server_getfileinfo (filename)
>     char *filename;
> {
>     Node *p = NULL;
> 
>     p = findnode (fileinfo_list, filename);
>     if (p != NULL)
>     {
>         return (struct logfile_info *) p->data;
>     }
>     else
>     {
>         return NULL;
>     }
> }
> 
> void
> server_delfileinfolist (void)
> {
>     if (fileinfo_list != NULL)
>         dellist (&fileinfo_list);
> }
> 
1929a2054
>     char *editor;
2030a2156,2183
> 	if (cp == NULL)
>         {
>             /* FIXME: Noel Yap (yap_noel@yahoo.com) 2001 Mar 15
>                This block is to support old clients.  It should be
>                removed once it's deemed that all clients send the
>                editor field.  IMHO, it should be safe to remove
>                by 2003 Mar 15 (ie in two years).
>             */
>             new->editor = getcaller();  /* to support old clients */
>         }
>         else
> 	{
> 	    *cp++ = '\0';
>             new->editor = cp;
> 
>             /* If there is another tab, ignore everything after it,
>                for future expansion.  */
>             cp = strchr (cp, '\t');
>             if (cp != NULL)
>             {
>                 *cp = '\0';
>             }
> 
>             /* lob off extra val fields */
>             {
>                 char *cp = NULL;
> 
>                 cp = strchr (new->val, '+');
2034a2188,2189
>             }
> 	}
2085a2241
>                    notify_list->editor,
2135c2291
<     
---
> 
2137c2293
<     
---
> 
2165c2321
<     
---
> 
2167c2323
<     
---
> 
2486c2642
<          
---
> 
2578c2734
<            
---
> 
2645c2801
<     
---
> 
2985c3141
< 	    
---
> 
2998c3154
< 		
---
> 
3136c3292
< 	    
---
> 
3263c3419
< 	
---
> 
3275c3431
< 	    
---
> 
3398c3554
<     
---
> 
4665a4822
>   REQ_LINE("FileInfo", serve_fileinfo, 0),
5096c5253
< 	
---
> 
5233c5390
<     
---
> 
5257c5414
<       
---
> 
5281c5438
< /* 
---
> /*
5350c5507
<         /* We need to make sure lines such as 
---
>         /* We need to make sure lines such as
5480c5637
< 	
---
> 
5498c5655
< 	
---
> 
5553c5710
<         /* Set CVS_Username here, in allocated space. 
---
>         /* Set CVS_Username here, in allocated space.
5676c5833
<     /* Make them pure. */ 
---
>     /* Make them pure. */
Index: src/server.h
===================================================================
RCS file: /home/nyap/.cvsroot/cvs/src/server.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -r1.1.1.1 -r1.1.1.1.4.1
121a122,124
> extern struct logfile_info *server_getfileinfo PROTO((char *));
> extern void server_delfileinfolist PROTO((void));
> 
Index: src/version.c
===================================================================
RCS file: /home/nyap/.cvsroot/cvs/src/version.c,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.4.1
diff -r1.1.1.1 -r1.1.1.1.4.1
6c6
<  * 
---
>  *
9c9
<  * 
---
>  *
15c15
< char *version_string = "Concurrent Versions System (CVS) 1.11";
---
> char *version_string = "Concurrent Versions System (CVS) 1.11 (multiple edits)";
75d74
< 	
