summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/fileattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cvs/src/fileattr.c')
-rw-r--r--contrib/cvs/src/fileattr.c656
1 files changed, 0 insertions, 656 deletions
diff --git a/contrib/cvs/src/fileattr.c b/contrib/cvs/src/fileattr.c
deleted file mode 100644
index ca6bd0e..0000000
--- a/contrib/cvs/src/fileattr.c
+++ /dev/null
@@ -1,656 +0,0 @@
-/* Implementation for file attribute munging features.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- 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. */
-
-#include "cvs.h"
-#include "getline.h"
-#include "fileattr.h"
-#include <assert.h>
-
-static void fileattr_read PROTO ((void));
-static int writeattr_proc PROTO ((Node *, void *));
-
-/* Where to look for CVSREP_FILEATTR. */
-static char *fileattr_stored_repos;
-
-/* The in-memory attributes. */
-static List *attrlist;
-static char *fileattr_default_attrs;
-/* We have already tried to read attributes and failed in this directory
- (for example, there is no CVSREP_FILEATTR file). */
-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
-fileattr_startdir (repos)
- const char *repos;
-{
- assert (fileattr_stored_repos == NULL);
- fileattr_stored_repos = xstrdup (repos);
- assert (attrlist == NULL);
- attr_read_attempted = 0;
- assert (unrecog_head == NULL);
-}
-
-static void
-fileattr_delproc (node)
- Node *node;
-{
- assert (node->data != NULL);
- free (node->data);
- node->data = NULL;
-}
-
-/* Read all the attributes for the current directory into memory. */
-static void
-fileattr_read ()
-{
- char *fname;
- FILE *fp;
- char *line = NULL;
- size_t line_len = 0;
-
- /* If there are no attributes, don't waste time repeatedly looking
- for the CVSREP_FILEATTR file. */
- if (attr_read_attempted)
- return;
-
- /* If NULL was passed to fileattr_startdir, then it isn't kosher to look
- at attributes. */
- assert (fileattr_stored_repos != NULL);
-
- fname = xmalloc (strlen (fileattr_stored_repos)
- + 1
- + sizeof (CVSREP_FILEATTR)
- + 1);
-
- strcpy (fname, fileattr_stored_repos);
- strcat (fname, "/");
- strcat (fname, CVSREP_FILEATTR);
-
- attr_read_attempted = 1;
- fp = CVS_FOPEN (fname, FOPEN_BINARY_READ);
- if (fp == NULL)
- {
- if (!existence_error (errno))
- error (0, errno, "cannot read %s", fname);
- free (fname);
- return;
- }
- attrlist = getlist ();
- while (1) {
- int nread;
- nread = getline (&line, &line_len, fp);
- if (nread < 0)
- break;
- /* Remove trailing newline. */
- line[nread - 1] = '\0';
- if (line[0] == 'F')
- {
- char *p;
- Node *newnode;
-
- p = strchr (line, '\t');
- if (p == NULL)
- error (1, 0,
- "file attribute database corruption: tab missing in %s",
- fname);
- *p++ = '\0';
- newnode = getnode ();
- newnode->type = FILEATTR;
- newnode->delproc = fileattr_delproc;
- newnode->key = xstrdup (line + 1);
- newnode->data = xstrdup (p);
- 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. */
- freenode (newnode);
- }
- else if (line[0] == 'D')
- {
- char *p;
- /* Currently nothing to skip here, but for future expansion,
- ignore anything located here. */
- p = strchr (line, '\t');
- if (p == NULL)
- error (1, 0,
- "file attribute database corruption: tab missing in %s",
- fname);
- ++p;
- if (fileattr_default_attrs) free (fileattr_default_attrs);
- fileattr_default_attrs = xstrdup (p);
- }
- 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);
- if (line != NULL)
- free (line);
- if (fclose (fp) < 0)
- error (0, errno, "cannot close %s", fname);
- attrs_modified = 0;
- free (fname);
-}
-
-char *
-fileattr_get (filename, attrname)
- const char *filename;
- const char *attrname;
-{
- Node *node;
- size_t attrname_len = strlen (attrname);
- char *p;
-
- if (attrlist == NULL)
- fileattr_read ();
- if (attrlist == NULL)
- /* Either nothing has any attributes, or fileattr_read already printed
- an error message. */
- return NULL;
-
- if (filename == NULL)
- p = fileattr_default_attrs;
- else
- {
- node = findnode (attrlist, filename);
- if (node == NULL)
- /* A file not mentioned has no attributes. */
- return NULL;
- p = node->data;
- }
- while (p)
- {
- if (strncmp (attrname, p, attrname_len) == 0
- && p[attrname_len] == '=')
- {
- /* Found it. */
- return p + attrname_len + 1;
- }
- p = strchr (p, ';');
- if (p == NULL)
- break;
- ++p;
- }
- /* The file doesn't have this attribute. */
- return NULL;
-}
-
-char *
-fileattr_get0 (filename, attrname)
- const char *filename;
- const char *attrname;
-{
- char *cp;
- char *cpend;
- char *retval;
-
- cp = fileattr_get (filename, attrname);
- if (cp == NULL)
- return NULL;
- cpend = strchr (cp, ';');
- if (cpend == NULL)
- cpend = cp + strlen (cp);
- retval = xmalloc (cpend - cp + 1);
- strncpy (retval, cp, cpend - cp);
- retval[cpend - cp] = '\0';
- return retval;
-}
-
-char *
-fileattr_modify (list, attrname, attrval, namevalsep, entsep)
- char *list;
- const char *attrname;
- const char *attrval;
- int namevalsep;
- int entsep;
-{
- char *retval;
- char *rp;
- size_t attrname_len = strlen (attrname);
-
- /* Portion of list before the attribute to be replaced. */
- char *pre;
- char *preend;
- /* Portion of list after the attribute to be replaced. */
- char *post;
-
- char *p;
- char *p2;
-
- p = list;
- pre = list;
- preend = NULL;
- /* post is NULL unless set otherwise. */
- post = NULL;
- p2 = NULL;
- if (list != NULL)
- {
- while (1) {
- p2 = strchr (p, entsep);
- if (p2 == NULL)
- {
- p2 = p + strlen (p);
- if (preend == NULL)
- preend = p2;
- }
- else
- ++p2;
- if (strncmp (attrname, p, attrname_len) == 0
- && p[attrname_len] == namevalsep)
- {
- /* Found it. */
- preend = p;
- if (preend > list)
- /* Don't include the preceding entsep. */
- --preend;
-
- post = p2;
- }
- if (p2[0] == '\0')
- break;
- p = p2;
- }
- }
- if (post == NULL)
- post = p2;
-
- if (preend == pre && attrval == NULL && post == p2)
- return NULL;
-
- retval = xmalloc ((preend - pre)
- + 1
- + (attrval == NULL ? 0 : (attrname_len + 1
- + strlen (attrval)))
- + 1
- + (p2 - post)
- + 1);
- if (preend != pre)
- {
- strncpy (retval, pre, preend - pre);
- rp = retval + (preend - pre);
- if (attrval != NULL)
- *rp++ = entsep;
- *rp = '\0';
- }
- else
- retval[0] = '\0';
- if (attrval != NULL)
- {
- strcat (retval, attrname);
- rp = retval + strlen (retval);
- *rp++ = namevalsep;
- strcpy (rp, attrval);
- }
- if (post != p2)
- {
- rp = retval + strlen (retval);
- if (preend != pre || attrval != NULL)
- *rp++ = entsep;
- strncpy (rp, post, p2 - post);
- rp += p2 - post;
- *rp = '\0';
- }
- return retval;
-}
-
-void
-fileattr_set (filename, attrname, attrval)
- const char *filename;
- const char *attrname;
- const char *attrval;
-{
- Node *node;
- char *p;
-
- if (filename == NULL)
- {
- p = fileattr_modify (fileattr_default_attrs, attrname, attrval,
- '=', ';');
- if (fileattr_default_attrs != NULL)
- free (fileattr_default_attrs);
- fileattr_default_attrs = p;
- attrs_modified = 1;
- return;
- }
- if (attrlist == NULL)
- fileattr_read ();
- if (attrlist == NULL)
- {
- /* Not sure this is a graceful way to handle things
- in the case where fileattr_read was unable to read the file. */
- /* No attributes existed previously. */
- attrlist = getlist ();
- }
-
- node = findnode (attrlist, filename);
- if (node == NULL)
- {
- if (attrval == NULL)
- /* Attempt to remove an attribute which wasn't there. */
- return;
-
- /* First attribute for this file. */
- node = getnode ();
- node->type = FILEATTR;
- node->delproc = fileattr_delproc;
- node->key = xstrdup (filename);
- node->data = xmalloc (strlen (attrname) + 1 + strlen (attrval) + 1);
- strcpy (node->data, attrname);
- strcat (node->data, "=");
- strcat (node->data, attrval);
- addnode (attrlist, node);
- }
-
- p = fileattr_modify (node->data, attrname, attrval, '=', ';');
- if (p == NULL)
- delnode (node);
- else
- {
- free (node->data);
- node->data = p;
- }
-
- attrs_modified = 1;
-}
-
-char *
-fileattr_getall (filename)
- const char *filename;
-{
- Node *node;
- char *p;
-
- if (attrlist == NULL)
- fileattr_read ();
- if (attrlist == NULL)
- /* Either nothing has any attributes, or fileattr_read already printed
- an error message. */
- return NULL;
-
- if (filename == NULL)
- p = fileattr_default_attrs;
- else
- {
- node = findnode (attrlist, filename);
- if (node == NULL)
- /* A file not mentioned has no attributes. */
- return NULL;
- p = node->data;
- }
- return xstrdup (p);
-}
-
-void
-fileattr_setall (filename, attrs)
- const char *filename;
- const char *attrs;
-{
- Node *node;
-
- if (filename == NULL)
- {
- if (fileattr_default_attrs != NULL)
- free (fileattr_default_attrs);
- fileattr_default_attrs = xstrdup (attrs);
- attrs_modified = 1;
- return;
- }
- if (attrlist == NULL)
- fileattr_read ();
- if (attrlist == NULL)
- {
- /* Not sure this is a graceful way to handle things
- in the case where fileattr_read was unable to read the file. */
- /* No attributes existed previously. */
- attrlist = getlist ();
- }
-
- node = findnode (attrlist, filename);
- if (node == NULL)
- {
- /* The file had no attributes. Add them if we have any to add. */
- if (attrs != NULL)
- {
- node = getnode ();
- node->type = FILEATTR;
- node->delproc = fileattr_delproc;
- node->key = xstrdup (filename);
- node->data = xstrdup (attrs);
- addnode (attrlist, node);
- }
- }
- else
- {
- if (attrs == NULL)
- delnode (node);
- else
- {
- free (node->data);
- node->data = xstrdup (attrs);
- }
- }
-
- attrs_modified = 1;
-}
-
-void
-fileattr_newfile (filename)
- const char *filename;
-{
- Node *node;
-
- if (attrlist == NULL)
- fileattr_read ();
-
- if (fileattr_default_attrs == NULL)
- return;
-
- if (attrlist == NULL)
- {
- /* Not sure this is a graceful way to handle things
- in the case where fileattr_read was unable to read the file. */
- /* No attributes existed previously. */
- attrlist = getlist ();
- }
-
- node = getnode ();
- node->type = FILEATTR;
- node->delproc = fileattr_delproc;
- node->key = xstrdup (filename);
- node->data = xstrdup (fileattr_default_attrs);
- addnode (attrlist, node);
- attrs_modified = 1;
-}
-
-static int
-writeattr_proc (node, data)
- Node *node;
- void *data;
-{
- FILE *fp = (FILE *)data;
- fputs ("F", fp);
- fputs (node->key, fp);
- fputs ("\t", fp);
- fputs (node->data, fp);
- fputs ("\012", fp);
- return 0;
-}
-
-void
-fileattr_write ()
-{
- FILE *fp;
- char *fname;
- mode_t omask;
- struct unrecog *p;
-
- if (!attrs_modified)
- return;
-
- if (noexec)
- return;
-
- /* If NULL was passed to fileattr_startdir, then it isn't kosher to set
- attributes. */
- assert (fileattr_stored_repos != NULL);
-
- fname = xmalloc (strlen (fileattr_stored_repos)
- + 1
- + sizeof (CVSREP_FILEATTR)
- + 1);
-
- strcpy (fname, fileattr_stored_repos);
- strcat (fname, "/");
- strcat (fname, CVSREP_FILEATTR);
-
- if (list_isempty (attrlist)
- && fileattr_default_attrs == NULL
- && unrecog_head == NULL)
- {
- /* There are no attributes. */
- if (unlink_file (fname) < 0)
- {
- if (!existence_error (errno))
- {
- error (0, errno, "cannot remove %s", fname);
- }
- }
-
- /* Now remove CVSREP directory, if empty. The main reason we bother
- is that CVS 1.6 and earlier will choke if a CVSREP directory
- exists, so provide the user a graceful way to remove it. */
- strcpy (fname, fileattr_stored_repos);
- strcat (fname, "/");
- strcat (fname, CVSREP);
- if (CVS_RMDIR (fname) < 0)
- {
- if (errno != ENOTEMPTY
-
- /* Don't know why we would be here if there is no CVSREP
- directory, but it seemed to be happening anyway, so
- check for it. */
- && !existence_error (errno))
- error (0, errno, "cannot remove %s", fname);
- }
-
- free (fname);
- return;
- }
-
- omask = umask (cvsumask);
- fp = CVS_FOPEN (fname, FOPEN_BINARY_WRITE);
- if (fp == NULL)
- {
- if (existence_error (errno))
- {
- /* Maybe the CVSREP directory doesn't exist. Try creating it. */
- char *repname;
-
- repname = xmalloc (strlen (fileattr_stored_repos)
- + 1
- + sizeof (CVSREP)
- + 1);
- strcpy (repname, fileattr_stored_repos);
- strcat (repname, "/");
- strcat (repname, CVSREP);
-
- if (CVS_MKDIR (repname, 0777) < 0 && errno != EEXIST)
- {
- error (0, errno, "cannot make directory %s", repname);
- (void) umask (omask);
- free (fname);
- free (repname);
- return;
- }
- free (repname);
-
- fp = CVS_FOPEN (fname, FOPEN_BINARY_WRITE);
- }
- if (fp == NULL)
- {
- error (0, errno, "cannot write %s", fname);
- (void) umask (omask);
- free (fname);
- return;
- }
- }
- (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. */
- for (p = unrecog_head; p != NULL; p = p->next)
- {
- fputs (p->line, fp);
- fputs ("\012", fp);
- }
-
- if (fclose (fp) < 0)
- error (0, errno, "cannot close %s", fname);
- attrs_modified = 0;
- free (fname);
-}
-
-void
-fileattr_free ()
-{
- /* Note that attrs_modified will ordinarily be zero, but there are
- a few cases in which fileattr_write will fail to zero it (if
- noexec is set, or error conditions). This probably is the way
- it should be. */
- dellist (&attrlist);
- if (fileattr_stored_repos != NULL)
- free (fileattr_stored_repos);
- fileattr_stored_repos = NULL;
- if (fileattr_default_attrs != NULL)
- free (fileattr_default_attrs);
- fileattr_default_attrs = NULL;
- while (unrecog_head)
- {
- struct unrecog *p = unrecog_head;
- unrecog_head = p->next;
- free (p->line);
- free (p);
- }
-}
OpenPOWER on IntegriCloud