summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/fileattr.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1997-05-15 22:46:24 +0000
committerpeter <peter@FreeBSD.org>1997-05-15 22:46:24 +0000
commit4f40fe8334ad5f056e1d9105f23fe7ac859c39ba (patch)
tree3b2f0092fa216d9f61059ba94b7f10b5bacf9496 /contrib/cvs/src/fileattr.c
parent8982e501c77217c860f79bba431f46a62b607a21 (diff)
downloadFreeBSD-src-4f40fe8334ad5f056e1d9105f23fe7ac859c39ba.zip
FreeBSD-src-4f40fe8334ad5f056e1d9105f23fe7ac859c39ba.tar.gz
Import of cvs-1.9.9-970515 onto vendor branch.
Obtained from: cyclic.com
Diffstat (limited to 'contrib/cvs/src/fileattr.c')
-rw-r--r--contrib/cvs/src/fileattr.c95
1 files changed, 69 insertions, 26 deletions
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;
OpenPOWER on IntegriCloud