From 4f40fe8334ad5f056e1d9105f23fe7ac859c39ba Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 15 May 1997 22:46:24 +0000 Subject: Import of cvs-1.9.9-970515 onto vendor branch. Obtained from: cyclic.com --- contrib/cvs/src/fileattr.c | 95 +++++++++++++++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 26 deletions(-) (limited to 'contrib/cvs/src/fileattr.c') diff --git a/contrib/cvs/src/fileattr.c b/contrib/cvs/src/fileattr.c index 827c69c..eda7753 100644 --- a/contrib/cvs/src/fileattr.c +++ b/contrib/cvs/src/fileattr.c @@ -8,11 +8,7 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + GNU General Public License for more details. */ #include "cvs.h" #include "getline.h" @@ -35,6 +31,14 @@ static int attr_read_attempted; /* Have the in-memory attributes been modified since we read them? */ static int attrs_modified; +/* More in-memory attributes: linked list of unrecognized + fileattr lines. We pass these on unchanged. */ +struct unrecog { + char *line; + struct unrecog *next; +}; +static struct unrecog *unrecog_head; + /* Note that if noone calls fileattr_get, this is very cheap. No stat(), no open(), no nothing. */ void @@ -45,6 +49,7 @@ fileattr_startdir (repos) fileattr_stored_repos = xstrdup (repos); assert (attrlist == NULL); attr_read_attempted = 0; + assert (unrecog_head == NULL); } static void @@ -84,7 +89,7 @@ fileattr_read () strcat (fname, CVSREP_FILEATTR); attr_read_attempted = 1; - fp = fopen (fname, FOPEN_BINARY_READ); + fp = CVS_FOPEN (fname, FOPEN_BINARY_READ); if (fp == NULL) { if (!existence_error (errno)) @@ -112,7 +117,12 @@ fileattr_read () newnode->delproc = fileattr_delproc; newnode->key = xstrdup (line + 1); newnode->data = xstrdup (p); - addnode (attrlist, newnode); + if (addnode (attrlist, newnode) != 0) + /* If the same filename appears twice in the file, discard + any line other than the first for that filename. This + is the way that CVS has behaved since file attributes + were first introduced. */ + free (newnode); } else if (line[0] == 'D') { @@ -123,7 +133,17 @@ fileattr_read () ++p; fileattr_default_attrs = xstrdup (p); } - /* else just ignore the line, for future expansion. */ + else + { + /* Unrecognized type, we want to just preserve the line without + changing it, for future expansion. */ + struct unrecog *new; + + new = (struct unrecog *) xmalloc (sizeof (struct unrecog)); + new->line = xstrdup (line); + new->next = unrecog_head; + unrecog_head = new; + } } if (ferror (fp)) error (0, errno, "cannot read %s", fname); @@ -137,8 +157,8 @@ fileattr_read () char * fileattr_get (filename, attrname) - char *filename; - char *attrname; + const char *filename; + const char *attrname; { Node *node; size_t attrname_len = strlen (attrname); @@ -180,8 +200,8 @@ fileattr_get (filename, attrname) char * fileattr_get0 (filename, attrname) - char *filename; - char *attrname; + const char *filename; + const char *attrname; { char *cp; char *cpend; @@ -202,8 +222,8 @@ fileattr_get0 (filename, attrname) char * fileattr_modify (list, attrname, attrval, namevalsep, entsep) char *list; - char *attrname; - char *attrval; + const char *attrname; + const char *attrval; int namevalsep; int entsep; { @@ -298,15 +318,13 @@ fileattr_modify (list, attrname, attrval, namevalsep, entsep) void fileattr_set (filename, attrname, attrval) - char *filename; - char *attrname; - char *attrval; + const char *filename; + const char *attrname; + const char *attrval; { Node *node; char *p; - attrs_modified = 1; - if (filename == NULL) { p = fileattr_modify (fileattr_default_attrs, attrname, attrval, @@ -314,6 +332,7 @@ fileattr_set (filename, attrname, attrval) if (fileattr_default_attrs != NULL) free (fileattr_default_attrs); fileattr_default_attrs = p; + attrs_modified = 1; return; } if (attrlist == NULL) @@ -346,17 +365,20 @@ fileattr_set (filename, attrname, attrval) } p = fileattr_modify (node->data, attrname, attrval, '=', ';'); - free (node->data); - node->data = NULL; if (p == NULL) delnode (node); else + { + free (node->data); node->data = p; + } + + attrs_modified = 1; } void fileattr_newfile (filename) - char *filename; + const char *filename; { Node *node; @@ -423,7 +445,9 @@ fileattr_write () strcat (fname, "/"); strcat (fname, CVSREP_FILEATTR); - if (list_isempty (attrlist) && fileattr_default_attrs == NULL) + if (list_isempty (attrlist) + && fileattr_default_attrs == NULL + && unrecog_head == NULL) { /* There are no attributes. */ if (unlink_file (fname) < 0) @@ -440,7 +464,7 @@ fileattr_write () strcpy (fname, fileattr_stored_repos); strcat (fname, "/"); strcat (fname, CVSREP); - if (rmdir (fname) < 0) + if (CVS_RMDIR (fname) < 0) { if (errno != ENOTEMPTY @@ -456,7 +480,7 @@ fileattr_write () } omask = umask (cvsumask); - fp = fopen (fname, FOPEN_BINARY_WRITE); + fp = CVS_FOPEN (fname, FOPEN_BINARY_WRITE); if (fp == NULL) { if (existence_error (errno)) @@ -481,7 +505,7 @@ fileattr_write () } free (repname); - fp = fopen (fname, FOPEN_BINARY_WRITE); + fp = CVS_FOPEN (fname, FOPEN_BINARY_WRITE); } if (fp == NULL) { @@ -491,13 +515,32 @@ fileattr_write () } } (void) umask (omask); + + /* First write the "F" attributes. */ walklist (attrlist, writeattr_proc, fp); + + /* Then the "D" attribute. */ if (fileattr_default_attrs != NULL) { fputs ("D\t", fp); fputs (fileattr_default_attrs, fp); fputs ("\012", fp); } + + /* Then any other attributes. */ + while (unrecog_head != NULL) + { + struct unrecog *p; + + p = unrecog_head; + fputs (p->line, fp); + fputs ("\012", fp); + + unrecog_head = p->next; + free (p->line); + free (p); + } + if (fclose (fp) < 0) error (0, errno, "cannot close %s", fname); attrs_modified = 0; -- cgit v1.1