diff options
Diffstat (limited to 'contrib/cvs/src/fileattr.c')
-rw-r--r-- | contrib/cvs/src/fileattr.c | 656 |
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); - } -} |